Java-----栈

目录

1.栈(Stack)

1.1概念

1.2栈的使用

1.3栈的模拟实现

1.4栈的应用场景

1.5栈、虚拟机栈、栈帧有什么区别呢


1.栈(Stack)

1.1概念

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈 顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。

出栈:栈的删除操作叫做出栈。出数据在栈顶。

1.2栈的使用

方法功能
Stack()构造一个空的栈
E push(E e)将e入栈,并返回e
E pop()将栈顶元素出栈并返回
E peek()获取栈顶元素
int size()获取栈中有效元素个数
boolean empty()检测栈是否为空
    public static void main(String[] args) {
Stack<Integer>stack=new Stack<>();
//进栈
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.push(5);System.out.println(stack);//出栈stack.pop();stack.pop();System.out.println(stack);//判断栈是否为空System.out.println(stack.empty());//获取栈顶元素System.out.println(stack.peek());//获取元素个数System.out.println(stack.size());}

1.3栈的模拟实现

使用数组实现

package MyStack;import java.util.Arrays;public class MyStack {public int[]elem;public int useSize=0;
//构造方法public MyStack() {this.elem =new int[10];}
//出栈public int pop(){if(empty()){throw new StackemptyExpection("栈为空,无法出栈");}return elem[useSize--];}
//进栈public void push(int val){if(isFull()){this.elem= Arrays.copyOf(elem,elem.length*2);}
elem[useSize]=val;
useSize++;}
//获取栈顶元素public int peek(){
return elem[useSize-1];}
//判断是否为空public boolean empty(){
return useSize==0;}
//判断是否满了public boolean isFull(){return useSize== elem.length;}}

1.4栈的应用场景

1. 改变元素的序列

1. 若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是()  

A: 1,4,3,2   B: 2,3,4,1   C: 3,1,4,2   D: 3,4,2,1    

答案:C

2.一个栈的初始状态为空。现将元素1、2、3、4、5、A、B、C、D、E依次入栈,然后再依次出栈,则元素出栈的顺序是( )。

A: 12345ABCDE   B: EDCBA54321   C: ABCDE12345   D: 54321EDCBA

答案:B

2. 将递归转化为循环

逆序打印链表

// 递归方式
void printList(Node head){if(null != head){printList(head.next);System.out.print(head.val + " ");}
}// 循环方式
void printList(Node head){if(null == head){return;}Stack<Node> s = new Stack<>();// 将链表中的结点保存在栈中Node cur = head;while(null != cur){s.push(cur);cur = cur.next;}// 将栈中的元素出栈while(!s.empty()){System.out.print(s.pop().val + " ");}
}

3.有效的括号

. - 力扣(LeetCode)

给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。

 方法:

创建一个栈用来存储左括号,遍历字符串,如果是左括号就将其进栈,否则判断其是否和栈顶括号匹配,如果栈顶没有元素返回false,如果匹配就出栈,遍历完看栈是否为空,不为空返回false,为空返回true

class Solution {public boolean isValid(String s) {
Stack<Character>stack=new Stack<>();
for(int i=0;i<s.length();i++){char ch=s.charAt(i);if(ch=='('||ch=='{'||ch=='['){stack.push(ch);}else{if(stack.isEmpty()){return false;}
char ch2=stack.peek();
if((ch==')'&&ch2=='(')||(ch=='}'&&ch2=='{')||(ch==']'&&ch2=='['))
{stack.pop();
}else{return false;
}}
}
if(!stack.isEmpty()){return false;
}
return true;}
}

4.逆波兰表达式求值

. - 力扣(LeetCode)

给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。

请你计算该表达式。返回一个表示表达式值的整数。

方法:

创建一个栈来存储数字,遍历字符串数组,如果是数字就进栈,不是就连续出栈两个数字进行计算,计算的结果再进栈,遍历完数组后,返回栈顶元素

class Solution {public int evalRPN(String[] tokens) {
Stack<Integer>stack=new Stack<>();
for(String str:tokens){if(!isOperator(str)){int x=Integer.parseInt(str);
stack.push(x);}else{
int val2=stack.pop();
int val1=stack.pop();
switch(str){
case "+":
stack.push(val1+val2);
break;
case "-":
stack.push(val1-val2);
break;
case "*":
stack.push(val1*val2);
break;
case "/":
stack.push(val1/val2);
break;
}}
}
return stack.pop();}
private boolean isOperator(String str){if(str.equals("+")||str.equals("-")||str.equals("/")||str.equals("*")){return true;}return false;
}
}

中缀表达式怎么变后缀表达式

将中缀表达式转换为后缀表达式可以通过以下步骤进行:

1. 初始化一个空栈用于存储运算符,以及一个空字符串用于存储后缀表达式。

2. 从左到右依次扫描中缀表达式的每个元素。

• 如果是操作数,直接添加到后缀表达式中。

• 如果是左括号,将其入栈。

• 如果是右括号,将栈中的运算符依次弹出并添加到后缀表达式中,直到遇到左括号,然后将左括号从栈中弹出。

• 如果是运算符:

• 若栈为空或栈顶为左括号,直接将运算符入栈。

• 若该运算符的优先级高于栈顶运算符的优先级,将其入栈。

• 若该运算符的优先级低于或等于栈顶运算符的优先级,将栈顶运算符弹出并添加到后缀表达式中,然后比较新的栈顶运算符,重复此操作,直到该运算符可以入栈。

3. 扫描完毕后,将栈中剩余的运算符依次弹出并添加到后缀表达式中。

例如,将中缀表达式“3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3”转换为后缀表达式:

扫描到“3”,是操作数,直接添加到后缀表达式,后缀表达式为“3”。

扫描到“+”,栈为空,入栈,栈内为“+”,后缀表达式为“3”。

扫描到“4”,是操作数,添加到后缀表达式,后缀表达式为“3 4”。

扫描到“”,“+”优先级低于“”,“*”入栈,栈内为“+ *”,后缀表达式为“3 4”。

扫描到“2”,是操作数,添加到后缀表达式,后缀表达式为“3 4 2”。

扫描到“/”,“”优先级高于“/”,将“”弹出,“/”入栈,栈内为“+ /”,后缀表达式为“3 4 2 *”。

扫描到“(”,入栈,栈内为“+ / (”,后缀表达式为“3 4 2 *”。

扫描到“1”,是操作数,添加到后缀表达式,后缀表达式为“3 4 2 * 1”。

扫描到“-”,栈顶为“(”,入栈,栈内为“+ / ( -”,后缀表达式为“3 4 2 * 1”。

扫描到“5”,是操作数,添加到后缀表达式,后缀表达式为“3 4 2 * 1 5”。

扫描到“)”,将栈中运算符依次弹出直到遇到“(”,“(”弹出,栈内为“+ / ”,后缀表达式为“3 4 2 * 1 5 -”。

扫描到“^”,“/”优先级低于“^”,“^”入栈,栈内为“+ / ^”,后缀表达式为“3 4 2 * 1 5 -”。

扫描到“2”,是操作数,添加到后缀表达式,后缀表达式为“3 4 2 * 1 5 - 2”。

扫描到“^”,“^”优先级高于栈顶“^”,入栈,栈内为“+ / ^ ^”,后缀表达式为“3 4 2 * 1 5 - 2”。

扫描到“3”,是操作数,添加到后缀表达式,后缀表达式为“3 4 2 * 1 5 - 2 3”。

扫描结束,将栈中运算符依次弹出添加到后缀表达式,最终后缀表达式为“3 4 2 * 1 5 - 2 ^ 3 ^ / + ”

5.栈的压入和弹出序列

栈的压入、弹出序列_牛客题霸_牛客网

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
1. 0<=pushV.length == popV.length <=1000
2. -1000<=pushV[i]<=1000
3. pushV 的所有数字均不相同

 方法:

遍历一遍pushV数组,先将pushV中的元素压栈,判断栈顶元素是否和popV的j下标元素相同,相同就出栈,继续判断,直到不相同为止,当遍历完pushV时,看栈是否为空,如果为空,则说明popV是可行的出栈序列,否则不是

    public boolean IsPopOrder (int[] pushV, int[] popV) {Stack<Integer>stack=new Stack<>();int j=0;for(int i=0;i<pushV.length;i++){
stack.push(pushV[i]);
while(!stack.empty()&&stack.peek()==popV[j]&&j<popV.length){stack.pop();j++;
}}return stack.empty();}
}

6.最小栈

. - 力扣(LeetCode)

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

实现 MinStack 类:

MinStack() 初始化堆栈对象。
void push(int val) 将元素val推入堆栈。
void pop() 删除堆栈顶部的元素。
int top() 获取堆栈顶部的元素。
int getMin() 获取堆栈中的最小元素。

 方法

构造方法创建一个普通栈和最小栈

push方法,普通栈是必须压栈的,当普通栈压栈完成后,比较普通栈和最小栈的栈顶元素,如果普通栈的栈顶元素小于或等于最小栈的栈顶元素,那么就对最小栈进行压栈

pop方法,接收普通栈的栈顶元素,普通栈出栈,如果栈顶元素和最小栈的栈顶元素相同,那么最小栈也出栈

top方法,如果普通栈为空,返回-1,否则返回普通栈的栈顶元素

getMin方法,如果最小栈为空,返回-1,否则返回最小栈的栈顶元素

class MinStack {
public Stack<Integer>stack;
public Stack<Integer>Minstack;public MinStack() {
this.stack=new Stack<>();
this.Minstack=new Stack<>();}public void push(int val) {
stack.push(val);
if(Minstack.empty()){Minstack.push(val);
}else{if(val<=Minstack.peek()){Minstack.push(val);}
}}public void pop() {
int popVal=stack.pop();
if(popVal==Minstack.peek()){Minstack.pop();
}}public int top() {
if(stack.empty()){return -1;
}
return stack.peek();}public int getMin() {
if(Minstack.empty()){return -1;
}
return Minstack.peek();}
}

1.5栈、虚拟机栈、栈帧有什么区别呢?

栈(Stack)是一种数据结构,具有“后进先出”的特点,常用于存储临时数据和函数调用信息。
虚拟机栈(Virtual Machine Stack)是 Java 虚拟机运行时数据区中的一部分,用于存储方法调用的相关信息,包括局部变量表、操作数栈、动态链接、方法出口等。
栈帧(Stack Frame)是虚拟机栈中的基本单位,每当一个方法被调用时,就会创建一个新的栈帧并压入虚拟机栈。栈帧包含了方法的局部变量、操作数栈、返回地址等信息。当方法执行完毕,对应的栈帧就会出栈。

总的来说,栈是一种通用的数据结构概念,虚拟机栈是 Java 虚拟机中基于栈这种数据结构实现的用于方法调用管理的区域,而栈帧是虚拟机栈中的具体存储单元,用于承载每个方法的相关运行信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/50415.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python】基础学习技能提升代码样例4:常见配置文件和数据文件读写ini、yaml、csv、excel、xml、json

一、 配置文件 1.1 ini 官方-configparser config.ini文件如下&#xff1a; [url] ; section名称baidu https://www.zalou.cnport 80[email]sender ‘xxxqq.com’import configparser # 读取 file config.ini # 创建配置文件对象 con configparser.ConfigParser() # 读…

EEtrade:区块链是什么

区块链&#xff0c;这个近年来频繁出现在我们视野中的术语&#xff0c;已经从一个技术小众圈的词汇&#xff0c;逐渐演变为全球关注的焦点。从比特币的诞生&#xff0c;到如今在金融、供应链、物联网等领域的广泛应用&#xff0c;区块链技术正在深刻地改变着我们的生活。那么&a…

我在高职教STM32——串口通信(5)

大家好,我是老耿,高职青椒一枚,一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次,同行应该都懂的,老师在课堂上教学几乎是没什么成就感的。正因如此,才有了借助 CSDN 平台寻求认同感和成就感的想法。在这里,我准备陆续把自己花了很多心思的教学设计分享…

深入解析 Java 的 switch 语句

深入解析 Java 的 switch 语句 在 Java 编程中&#xff0c;switch 语句是一种常用的控制流语句&#xff0c;它能够根据变量的不同值执行不同的代码块。与 if-else 语句相比&#xff0c;switch 语句在处理多个条件判断时更加简洁和清晰&#xff0c;尤其适用于对一个变量的多个可…

Godot入门 01Godot介绍

Unity大神&#xff0c;YouTube百万游戏开发者的启蒙老师&#xff0c;Brackeys&#xff0c;携 Godot 新手教程&#xff0c;正式回归。 转自&#xff1a;https://youtu.be/LOhfqjmasi0?si4RguI6-pXHZ2mk9K 资产&#xff1a;https://brackeysgames.itch.io/brackeys-platformer-b…

病理多示例学习仓库介绍(持续更新中)

开源项目介绍&#xff1a;MIL_BASELINE 项目概览 MIL_BASELINE 是一个集成了多种多实例学习方法&#xff08;MIL&#xff09;的统一框架库&#xff0c;旨在简化多实例学习模型的开发与应用。它不仅整合了多种MIL方法&#xff0c;还提供了统一的数据集接口和常用的数据集划分方…

C++的编译方式和文件扩展名,C++的头文件,以及C++的标准输入和输出

本文介绍C++的编译方式和文件扩展名,C++的头文件,以及C++的标准输入和输出 1.编译方式和文件扩展名 2.头文件 3.标准输入输出 //vi 01first.cpp#include <iostream>int main(void) {std::cout<<"hello world"<<std::endl;return 0;}1.1编译方式…

【linux】Shell脚本三剑客之grep和egrep命令的详细用法攻略

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…

LK漏感值在网络变压器测试中是否有很大的作用?

今天客户一个产品异常问题&#xff0c;就是说LK漏感值严重超标产品规格书参数&#xff0c;今天我们讲讲这个参数在网络变压器其中的影响。LK漏感值在网络变压器的测试和性能评估中扮演着重要的角色。漏感&#xff0c;或称为漏磁场感抗&#xff0c;是指变压器中不参与主要能量传…

2024.7.24

预处理 在计算机编程和算法设计中&#xff0c;“预处理”通常指在正式的处理或计算之前&#xff0c;对数据或操作进行的一些预先的处理和准备工作。 目的 预处理的目的通常包括&#xff1a; 优化性能&#xff1a;通过提前计算或整理一些数据&#xff0c;减少后续主要计算过…

万字长文说说C#和Rust_Cangjie们的模式匹配

C#11新增列表模式后&#xff0c;这个从C#6就开始的特性&#xff0c;算是拼接好了模式匹配的最后一块拼图。对比Swift、Rust或Cangjie这类先天支持模式匹配的语言&#xff0c;能否一战&#xff1f;今天就来全面battle一下。Swift、Rust和Cangjie的模式匹配&#xff0c;一肪相承&…

springboot会员信息管理系统-计算机毕业设计源码38258

目 录 摘要 1 绪论 1.1 研究背景 1.2 研究意义 1.3开发技术 1.3.1 Spring Boot框架 1.3.2 Java语言 1.3.3 MySQL数据库 1.4论文结构与章节安排 2系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 登录流程 2.2.2数据删除流程 2.3 系统功能分析 2.4 系统用例分析…

代码审计:Bluecms v1.6

代码审计&#xff1a;Bluecms v1.6 漏洞列表如下(共计32个漏洞&#xff0c;附Exp&#xff0c;按时间顺序)&#xff1a; 未完待续… 1、user.php 766行处存在任意文件删除漏洞 Exp:http://127.0.0.3/bluecms/user.php?actedit_user_info Post&#xff1a;face_pic32.php el…

动静资源的转发操作

目录 Nginx中的location指令 静态资源的转发 动态资源的转发 注意事项 深入研究 如何在Nginx中实现对特定后缀文件的静态资源进行反向代理&#xff1f; Nginx中location指令的优先级是怎样确定的&#xff1f; 为什么在使用proxy_pass时要区分是否带有斜杠&#xff1f; N…

《Java初阶数据结构》----8.<java对象的比较总结>

目录 前言 一、Java对象的比较 1.1基本类型的比较 1.2 对象比较的问题&#xff08;与equals&#xff09; 1.3对象的比较 &#xff08;三种常用方式&#xff09; 1.重写equals方法 2.基于Comparble接口类的比较 3.基于比较器比较&#xff08;Comparator接口&#xff09; …

秒懂C++之string类(下)

目录 一.接口说明 1.1 erase 1.2 replace&#xff08;最好别用&#xff09; 1.3 find 1.4 substr 1.5 rfind 1.6 find_first_of 1.7 find_last_of 二.string类的模拟实现 2.1 构造 2.2 无参构造 2.3 析构 2.4.【】运算符 2.5 迭代器 2.6 打印 2.7 reserve扩容 …

大模型算法面试题(十二)

本系列收纳各种大模型面试题及答案。 1、领域模型Continue PreTrain数据如何选取 在领域模型的Continue PreTrain&#xff08;持续预训练&#xff09;过程中&#xff0c;数据选取是一个至关重要的步骤&#xff0c;它直接影响模型在特定领域上的性能和泛化能力。以下是一些关于…

react native FlatList 组件滚动问题

版本"react-native": "0.74.2", <FlatListstyle{{width: 100%}}ref{flatListRef}data{list}renderItem{chatItem}keyExtractor{item > item.id}// onScroll{handleScroll}onContentSizeChange{() > {// 内容大小变化时&#xff0c;如果未手动滚动…

JavaScript在现代Web开发中的高级特性与趋势

介绍随着Web技术的飞速发展&#xff0c;JavaScript的角色日益重要&#xff0c;不仅限于前端逻辑处理&#xff0c;还涉及到后端服务、移动应用等多个领域。阐述掌握JavaScript高级特性对于开发高性能、可扩展Web应用的重要性。 1. ES6新特性概览 箭头函数&#xff1a;更简洁的…

Transformer-Bert---散装知识点---mlm,nsp,较之经典tran的区别和实际应用方式

本文记录的是笔者在了解了transformer结构后嗑bert中记录的一些散装知识点&#xff0c;有时间就会整理收录&#xff0c;希望最后能把transformer一个系列都完整的更新进去。 1.自监督学习 bert与原始的transformer不同&#xff0c;bert是使用大量无标签的数据进行预训练&#…