当前位置: 首页 > news >正文

Java数据结构——Stack

Stack

  • 栈的概念和使用
    • 栈的概念
    • 栈的使用
  • 栈的应用
    • 出栈元素序列
    • 有效的括号
    • 栈的压入、弹出序列
    • 逆波兰表达式
    • 最小栈

栈的概念和使用

栈的概念

栈(Stack):一种特殊的线性表,只允许再栈的一端进行插入和删除元素,这一端点被称为栈顶另一端就是栈顶
栈中有两种使用:
入栈(push):插入数据进入栈中,入栈在栈顶
出栈(pop):删除栈中数据,出的是栈顶的数据
遵循的是先入后出的原则

在这里插入图片描述

栈的使用

方法功能
Stack()构造空的栈
E push(E e)将e入栈,返回e
E pop()将栈顶元素取出
E peek()获取栈顶元素
int size()栈的有效元素个数
boolean empty()判断栈是否为空

E push(E e) 将e入栈,返回e

public class Test {public static void main(String[] args) {Stack<Integer> stack = new Stack<>();stack.push(1);stack.push(2);stack.push(10);System.out.println(stack);}
}

运行结果如下
在这里插入图片描述

E pop() 将栈顶元素取出
E peek() 获取栈顶元素

public class Test {public static void main(String[] args) {Stack<Integer> stack = new Stack<>();stack.push(1);stack.push(2);stack.push(10);System.out.println(stack);int ret = stack.pop();//10 ,取出栈顶元素int ret1 = stack.peek();//2 //获取栈顶元素是多少System.out.println(ret);System.out.println(ret1);System.out.println("出栈后"+stack);//出栈后,栈中数据 1 2}
}

这里的pop是出栈的意思,而peek()只是获取其栈顶元素,并不是出栈,不会影响栈中元素
所以这里会取出栈顶元素10 而 在获取栈顶元素是2,最终栈中元素是1 2
在这里插入图片描述

int size() 栈的有效元素个数
boolean empty() 判断栈是否为空

public class Test {public static void main(String[] args) {Stack<Integer> stack = new Stack<>();stack.push(1);stack.push(2);stack.push(3);stack.push(5);stack.push(11);System.out.println(stack.size());//栈的元素个数 5 System.out.println(stack.empty());//这里栈不为空,false}
}

在这里插入图片描述

栈的应用

出栈元素序列

题目:若进栈序列为 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
A : 如果是1进栈,1出栈,在将1 2 3放入进去再出栈,这样出栈结果就1 4 3 2
B: 1进栈,先不出来,2 3 4依次进栈后就出栈,这样结果出栈结果为 2 3 4 1
C: 先出3 说明 1 2 3已经进栈了,3 出栈 2就是栈顶,不可以直接出1,所以错误
D 1 2 进栈,3 4分别进栈后出栈,最后出栈2 1结果为 3 4 2 1
在这里插入图片描述
C选项错误,所以选C

有效的括号

在这里插入图片描述

目的:括号是否可以左右匹配成功 “()” 或者 "([ ])"类型的都是匹配成功
思路:1创建一个Character类型的栈
2.如果遇到左边括号就将其放入栈中遇到右括号就与栈顶括号元素进行匹配,匹配不成功就直接返回false,匹配成功就继续向后匹配,入栈重复操作
3 在匹配的时候,如果栈为空,返回false
4.最后右括号匹配完成,但是栈不为空也返回false

在这里插入图片描述
在这里插入图片描述

1.这里再进行匹配的时候如果栈为空说明没有其右括号左边没有左括号入栈
2.如果匹配失败直接
3.最后字符串遍历完了,但是不为空,说明栈中的左括号没有全部匹配
这上面三种情况不符合要求直接返回false
class Solution {public boolean isValid(String s) {//创建一个Character的栈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{//匹配//1.判断栈是否为空if(stack.empty()){return false;}//2.出栈进行匹配char ch2 = stack.peek();if(ch2=='('&&ch==')'||ch2=='['&&ch==']'||ch2=='{'&&ch=='}'){stack.pop();}else{//不匹配return false;}}}//最后如果栈不为空,说明还有没匹配的if(!stack.empty()){return false;}return true;}
}

栈的压入、弹出序列

在这里插入图片描述

目的:有一个所有数都不相同的pushV数组压栈顺序,有一个和压栈的数相同出栈顺序,判断这个出栈顺序是否正确
思路:1.遍历这个pushV,将其元素进行入栈,2.并进行判断,栈顶元素是否与出栈顺序相同,相同就出栈,不相同就继续入栈,继续判断,重复操作
最后遍历完整个pushV数组,如果栈为空,说明其出栈顺序正确

在这里插入图片描述
在这里插入图片描述

1.这里的进行栈顶元素与popV判断明显是个while循环,因为可能连续出栈
2.并且这个循环不仅要判断是否相同也要注意栈不为空再进行判断
3.遍历完整个pushV数组后,最后如果栈为空说明出栈顺序是对的返回true,反之是false
import java.util.*;public boolean IsPopOrder (int[] pushV, int[] popV) {// write code hereStack<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++;stack.pop();//出栈}}//如果最后stack为空,说明成功了return stack.empty();}
}

逆波兰表达式

在这里插入图片描述
逆波兰式
在这里插入图片描述

目的:给一个逆波兰表达式,求出其结果
思路:使用栈进行计算,遇到数字就入栈,反之就是运算符,就要出栈进行计算

在这里插入图片描述
在这里插入图片描述

1.这里就是遇到数字字符就进行入栈,这里注意将数字字符转为数字,
2.遇到运算符就要计算,将计算结果入栈
3.最后返回栈顶数据就是计算结果
class Solution {public int evalRPN(String[] tokens) {Stack<Integer> stack = new Stack();for(String str: tokens){if(!isOperator(str)){stack.push(Integer.valueOf(str));//转换为数字入栈}else{//反之就出栈计算//将计算结果入栈int val1 = stack.pop();int val2 = stack.pop();switch(str){case "+":stack.push(val2+val1);break;case "-":stack.push(val2-val1);break;case "*":stack.push(val2*val1);break;case "/":stack.push(val2/val1);break;}}}return stack.pop();}//判断是不是运算符private boolean  isOperator(String s){if(s.equals("+")||s.equals("-")||s.equals("*")||s.equals("/")){return true;}return false;}
}

最小栈

在这里插入图片描述

目的:获取其栈中最小元素
思路:就是创建两个栈,1.正常栈一个栈是正常将所有元素依靠顺序入栈,出栈
2.最小栈用来放栈中最小元素,栈顶是最小元素,这样获取最小元素的效率是O(1)

>

在这里插入图片描述

注意这里在入栈的时候也要将和最小栈相同的元素也要放入进去
出栈的时候,也要注意栈的最小元素可能发生变化,最小栈可能也要出栈
这时候无论如何,最小栈栈顶就是栈中最小的元素
class MinStack {private Stack<Integer> stack;private Stack<Integer> minStack;public MinStack() {stack = new Stack<>();minStack = new Stack<>();}public void push(int val) {//将=最小栈顶元素的值也要放入最小栈if(minStack.empty()||val<=minStack.peek()){minStack.push(val);}stack.push(val);}public void pop() {//注意这里如果出栈的话,最小值可能发生变化if(stack.peek().equals(minStack.peek())){minStack.pop();}stack.pop();}public int top() {return stack.peek();  }public int getMin() {return minStack.peek();}
}

相关文章:

  • 机器学习(10)——神经网络
  • 代码随想录算法训练营第五十九天 | 1.ford算法精讲 卡码网94.城市间货物运输
  • 用python借用飞书机器人群发布定期内容
  • Eclipse 插件开发 3 菜单栏
  • 2025.04.26-饿了么春招笔试题-第一题
  • c++ package_task
  • 【Hive入门】Hive分桶表深度解析:从哈希分桶到Join优化的完整指南
  • Ubuntu编译opencv源码
  • SpringBoot实现的后端开发
  • 【计算机视觉】CV实战项目 -深度解析PaddleSegSharp:基于PaddleSeg的.NET图像分割解决方案
  • 数值数据处理的黄金法则:构建高质量机器学习模型的基石‌
  • per-task affinity 是什么?
  • 思科路由器重分发(静态路由+OSPF动态路由+RIP动态路由)
  • 配置文件的四级分类
  • 在Mybatis中为什么要同时指定扫描mapper接口和 mapper.xml 文件,理论单独扫描 xml 文件就可以啊
  • 数字IC后端实现教程之InnovusICC2添加Tie High/Low cell脚本
  • 4月25日日记(补)
  • 山东大学软件学院项目实训-基于大模型的模拟面试系统-前端美化滚动条问题
  • 桌面端开发技术栈选型:开启高效开发之旅
  • Eigen库编译
  • 没有雷军的车展:老外扎堆,萌车、机器狗谁更抢镜?| 湃客Talk
  • 哈马斯同意释放剩余所有以方被扣押人员,以换取停火五年
  • 谁将主导“视觉大脑”?中国AI的下一个超级赛道
  • 重新认识中国女性|婚姻,古代传统家庭再生产的根本之道
  • 五粮液一季度净利增长5.8%,今年营收与宏观经济指标保持一致
  • 中国驻英国大使郑泽光:中国需要世界,世界也需要中国