目录
1. 概念
栈 :一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈 顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO( Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈, 入数据在栈顶。
出栈:栈的删除操作叫做出栈。 出数据在栈顶。
2.栈的使用
public static void main(String[] args) {
Stack<Integer> s = new Stack();
s.push(1);
s.push(2);
s.push(3);
s.push(4);
System.out.println(s.size()); // 获取栈中有效元素个数---> 4
System.out.println(s.peek()); // 获取栈顶元素---> 4
s.pop(); // 4出栈 ,栈中剩余1 2 3 ,栈顶元素为3
System.out.println(s.pop()); // 3出栈 ,栈中剩余1 2 栈顶元素为3
if(s.empty()){
System.out.println("栈空");
}else{
System.out.println(s.size());
}
}
3.栈的模拟实现
从上图中可以看到, Stack继承了Vector ,Vector和ArrayList类似,都是动态的顺序表,不同的是Vector是线程安全的。
public class MyStack {
private int[] elem;
private int usedSize;
public MyStack() {
this.elem = new int[5];
}
public void push(int val){
if(isFull()){
elem = Arrays.copyOf(elem,2*elem.length);
}
elem[usedSize] = val;
usedSize++;
}
public int pop(){
//判断栈不为空
if(isEmpty()){
throw new StackEmptyException("栈为空");
}
return elem[--usedSize];
}
public boolean isFull(){
return usedSize == elem.length;
}
public boolean isEmpty(){
return usedSize == 0;
}
}
4.栈相关OJ题
1.括号匹配
class Solution {
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
if(s.length()<=1){return false;}
for(int i = 0;i<s.length();i++){
char ch = s.charAt(i);
if(ch=='(' || ch=='[' || ch=='{'){
stack.push(ch);
}else{
if(stack.empty()){
return false;
}else{
char tmp = stack.peek();
if(ch==')'&& tmp=='(' || ch==']'&& tmp=='[' || ch=='}'&& tmp=='{'){
stack.pop();
}else{
return false;
}
}
}
}
if(!stack.empty()){
return false;
}
return true;
}
}
2.逆波兰表达式求值
class Solution {
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();
for(String s : tokens){
if(!isOpera(s)){
stack.push(Integer.parseInt(s));
}else{
int num2 = stack.pop();
int num1 = stack.pop();
switch(s){
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.pop();
}
public boolean isOpera(String x){
if(x.equals("+") || x.equals("-") ||x.equals("*") || x.equals("/")){
return true;
}
return false;
}
}
3.最小栈
class MinStack {
private Stack<Integer> stack;
private Stack<Integer> minStack;
public MinStack() {
stack = new Stack<Integer>();
minStack = new Stack<Integer>();
}
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() {
if(stack.empty()){
return;
}
int val = stack.pop();
if(minStack.peek()==val){
minStack.pop();
}
}
public int top() {
if(stack.empty()){
return -1;
}
return stack.peek();
}
public int getMin() {
if(minStack.empty()){
return -1111;
}
return minStack.peek();
}
}