❣博主主页: 33的博客❣
▶️文章专栏分类:数据结构◀️
🚚我的代码仓库: 33的代码仓库🚚
🫵🫵🫵关注我带你学更多数据结构知识
目录
- 1.前言
- 2.概念
- 3.栈的使用
- 4.栈的应用场景
- 4.1有效的括号
- 4.2逆波兰表达式
- 4.3栈的压入弹出序列
- 4.4最小栈
- 5.总结
1.前言
最近淄博烧烤的热度很大啊,同学们想去淄博吃吃烤串吗?那想一想,在我们串肉的时候,最先串上的肉,是不是最后在被我们吃到呢?其实这就是日常生活在的一个“栈”,在数据结构中栈又是什么样子的呢?接下来,博主将详细介绍栈的相关知识。
2.概念
栈: 一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守 后进先出LIFO(Last In First Out)的原则。
3.栈的使用
注意
pop()与peek()的区别:pop是将栈顶元素出栈,peek只是瞄一眼并不出栈
从上图中可以看到,Stack继承了Vector,Vector和ArrayList类似,都是动态的顺序表,不同的是Vector是线程安全的。
4.栈的应用场景
例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,1、2、3入栈以后,3再出栈,此时栈顶为2,只能出2,不能出
4.1有效的括号
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效:OJ链接
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;}if(ch=='}'&&stack.peek()=='{'||ch==')'&&stack.peek()=='('||ch==']'&&stack.peek()=='['){stack.pop();}else{return false;}} }if(!stack.isEmpty()){return false;}return true; }
4.2逆波兰表达式
给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。
请你计算该表达式:OJ链接
public int evalRPN(String[] tokens) {Stack<Integer> stack=new Stack<>();for (String X:tokens){if(!isOperation(X)){stack.push(Integer.parseInt(X));}else {int num2=stack.pop();int num1=stack.pop();switch (X){case "+":stack.push(num1+num2);break;case "-":stack.push(num1-num2);break;case "*":stack.push(num1*num2); break;case "/":stack.push(num1/num2);break;}}}return stack.peek();}private boolean isOperation(String x) {if(x.equals("+")||x.equals("-")||x.equals("*")||x.equals("/")){return true;}return false;}
4.3栈的压入弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序:OJ链接
解题思路:
假设入栈顺序是:[1,2,3,4,5],出栈顺序是:[4,3,5,1,2]
每次入栈一个元素后检查栈顶元素,和出栈的元素进行比较,如果相同,那么此元素出栈。
如果结束后,栈内依然有元素,那么第二个序列是否可能为该栈的弹出顺序。
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.isEmpty()&&j<popV.length&&popV[j]==stack.peek()){stack.pop();j++;}}return stack.isEmpty();}
4.4最小栈
设置一个最小栈,并能在常数时间内检索到最小元素的栈:OJ链接
解题思路
创建两个栈,一个用于存放所有元素,一个用于存放最小元素,
入栈时,把入栈元素和最小栈的栈顶元素m进行比较,如小于或等于m,则也存入最小栈
出栈时,把出栈元素与m比较,如果相同则最小栈也出栈。
public class MinStack {Stack<Integer> minStack;Stack<Integer> stack;public MinStack() {minStack =new Stack<>();stack=new Stack<>();}void push(int val){stack.push(val);if(minStack.isEmpty()){minStack.push(val);}else {if (val<=minStack.peek()){minStack.push(val);}}}void pop(){int a=stack.pop();if(!minStack.isEmpty()&&a==minStack.peek()){minStack.pop();}}int top(){return stack.peek();}int getMin(){if(!minStack.isEmpty()){return minStack.peek();}return -1;}
}
5.总结
本篇文章,主要讲解了最小栈的概念,栈的使用,栈的应用场景,感兴趣的同学可以自己实现一个栈。
下期预告:队列