栈数据结构

1,概念

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

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

出栈(pop

复制代码
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());
}
}

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

栈在现实生活中的例子:

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());
}
}

如图:

从上图中可以看到,Stack继承了Vector,Vector和ArrayList类似,都是动态的顺序表,不同的是Vector是线程安 全的。

3 模拟实现一个栈

复制代码
import java.util.Arrays;

public class MyStack {
    public  int[] elem;
    public  int usedSize;

    public MyStack(){
        this.elem = new int[10];
    }
    public void push(int val){
        if(isFull()){
            //扩容
            elem = Arrays.copyOf(elem,2*elem.length);
        }
        elem[usedSize] = val;
        usedSize++;
    }
    public boolean isFull(){
        return usedSize == elem.length;
    }
    public int pop(){
        if(empty()){
            return -1;
        }
        int oldval = elem[usedSize-1];
        usedSize--;
        return oldval;


    }
    public int peek(){
        if(empty()){
            return -1;
        }
        int oldval = elem[usedSize-1];

        return oldval;


    }
    public boolean empty(){
        return usedSize == 0;
    }


}

public class Test {
    public static void main(String[] args) {
        MyStack myStack = new MyStack();
        myStack.push(1);
        myStack.push(2);
        myStack.push(3);
        System.out.println(myStack.pop());
        System.out.println(myStack.peek());
    }
}

4 栈的应用场景

1. 改变元素的序列

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

: 1,4,3,2

B: 2,3,4,1

C: 3,1,4,2

D: 3,4,2,1

解析:1、2、3入栈以后,3再出栈,此时栈顶为2,只能出2,不能出其他

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

A: 12345ABCDE

B: EDCBA54321

C: ABCDE12345

D: 54321EDCBA

2 逆波兰表达式求值OJ链接

我们先来了解一下中缀表达式和后缀表达式:

复制代码
class Solution {
    public int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();
       for(int i = 0; i< tokens.length;i++){
            String tmp = tokens[i];
                      if(!isOpearation(tmp)){
                    Integer val = Integer.valueOf(tmp);
                    stack.push(val);

                }else{
                    // + - / *
                    Integer val2 = stack.pop();
                    Integer val1 = stack.pop();
                    
                    switch(tmp){
                        case "+":
                        Integer ret1 = val1+val2;
                        stack.push(ret1);
                        break;
                        case "-":
                        Integer ret2 = val1-val2;
                        stack.push(ret2);
                        break;
                        case "*":
                        Integer ret3 = val1*val2;
                        stack.push(ret3);
                        break;
                        case "/":
                        Integer ret4 = val1/val2;
                        stack.push(ret4);
                        break;                     
                    }                    
                }           
        }
        return stack.pop();
       }
    public boolean isOpearation(String s){
        if(s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/")){
            return true;
        }
        return false;
    }
}

3. 括号匹配 OJ链接

复制代码
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);
            //1,左括号入栈
            if(ch == '(' || ch == '{' || ch == '['){
                stack.push(ch);
            }else{
                //2.遇到了右括号
                if(stack.empty()){
                    return false;
                }else{
                    //3.取栈顶元素的左括号看和当前右括号是否匹配
                    char chL = stack.peek();
                    if(chL == '(' && ch == ')' || chL == '[' && ch == ']'
                    ||chL == '{' && ch == '}'){
                        //4.证明当前一对括号是匹配的
                        stack.pop();
                    }else{
                        //5,当前括号不匹配
                        return false;
                    }
                }
            }
             
        }
        return stack.empty();
    }  
}

4 出栈入栈次序匹配OJ链接

复制代码
public boolean IsPopOrder (int[] pushV, int[] popV) {
        // write code here
        Stack<Integer> stack = new Stack<>();
        int j = 0;
        for(int i = 0; i<pushV.length;i++){
            stack.push(pushV[i]);
            while(j<popV.length && !stack.empty()
            && stack.peek() == popV[j]){
                stack.pop();
                j++;
            }
        }
        return stack.empty();
    }
}
相关推荐
呼啦啦啦啦啦啦啦啦35 分钟前
常见的排序算法
java·算法·排序算法
anlogic1 小时前
Java基础 8.18
java·开发语言
胡萝卜3.02 小时前
数据结构初阶:排序算法(一)插入排序、选择排序
数据结构·笔记·学习·算法·排序算法·学习方法
lyx33136967592 小时前
Pandas数据结构详解Series与DataFrame
数据结构·pandas
练习时长一年2 小时前
AopAutoConfiguration源码阅读
java·spring boot·intellij-idea
散1123 小时前
01数据结构-交换排序
数据结构·算法
源码宝3 小时前
【智慧工地源码】智慧工地云平台系统,涵盖安全、质量、环境、人员和设备五大管理模块,实现实时监控、智能预警和数据分析。
java·大数据·spring cloud·数据分析·源码·智慧工地·云平台
David爱编程4 小时前
面试必问!线程生命周期与状态转换详解
java·后端
LKAI.5 小时前
传统方式部署(RuoYi-Cloud)微服务
java·linux·前端·后端·微服务·node.js·ruoyi
HeyZoeHey5 小时前
Mybatis执行sql流程(一)
java·sql·mybatis