1、概念
->栈是一种特殊的线性表。栈只允许在固定的一端进行插入与删除操作。
->栈的特点:先进后出,后进先出
->压栈:栈的插入操作。
出栈:栈的删除操作。
入数据与出数据都在栈顶。
eg:
![](https://img-blog.csdnimg.cn/img_convert/327e4499b53b4b29ab833ec535592c0d.png)
2、栈的使用
(1)构造一个空的栈
E可以表示任意引用数据类型,如Integer,String等
Stack<E> stack = new Stack();
(2)入栈
stack.push(1);
(3)出栈
stack.pop();
(4)获取栈顶元素
System.out.println(stack.peek());
(5)判断栈是否为空
stack.empty(); //返回true 或者 false
(6)获取栈中有效元素个数
System.out.println(stack.size());
3、栈的模拟实现
![](https://img-blog.csdnimg.cn/img_convert/95aec0157e244665b3952a1654930c69.png)
![](https://img-blog.csdnimg.cn/img_convert/e1cd7fe762bd4d64b7c384975a2bd7cb.png)
4、栈的应用
(1)不可能的出栈顺序
![](https://img-blog.csdnimg.cn/img_convert/1543885752714f389126c7461d989ecb.png)
(2)逆序打印链表
![](https://img-blog.csdnimg.cn/img_convert/4b60a4df57c340d2b36e4c309e8f92f5.png)
(3)括号匹配
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;
}
//看是否匹配
if(stack.peek()=='(' && ch == ')' || stack.peek()=='[' && ch == ']' || stack.peek()=='{' && ch == '}'){
stack.pop();
}else{
//不匹配
return false;
}
}
}
if(stack.isEmpty()){
return true;
}else{
//左括号多
return false;
}
}
}
(4)逆波兰表达式求值【后缀表达式】
class Solution {
public int evalRPN(String[] tokens) {
Stack<Integer> s = new Stack<>();
for(String str : tokens){
//不是操作符就是数字
if(!isOperation(str)){
//是数字就入栈
s.push(Integer.parseInt(str));
}else{
int num2 = s.pop();
int num1 = s.pop();
switch(str){
case "+":
s.push(num1+num2);
break;
case "-":
s.push(num1-num2);
break;
case "*":
s.push(num1*num2);
break;
case "/":
s.push(num1/num2);
break;
}
}
}
return s.pop();
}
private boolean isOperation(String s){
//字符串的比较用equals,不能==
if(s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/")){
return true;
}else{
return false;
}
}
}