栈数据结构

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();
    }
}
相关推荐
她说彩礼65万4 分钟前
C# Activator详解
java·服务器·c#
-大头.4 分钟前
JDK 25革新:Java确定性性能新时代
java·开发语言
weixin_307779139 分钟前
Jenkins LDAP插件:企业级CI/CD的身份认证中枢
java·ci/cd·jenkins
Yupureki9 分钟前
《算法竞赛从入门到国奖》算法基础:入门篇-高精度
c语言·数据结构·c++·算法·visual studio
AM越.10 分钟前
Java设计模式超详解--责任链设计模式(含uml图)
java·设计模式·uml
ChrisitineTX18 分钟前
K8s 环境下的 Java 诡异停顿:CPU 没满,为什么 Pod 被 CFS Quota 限制得动弹不得?
java·容器·kubernetes
潇I洒19 分钟前
Ubuntu Linux 24.04 安装JAVA环境openjdk-21.0.2
java·linux·ubuntu
被闲置的鱼21 分钟前
麒麟OS各种环境安装脚本,达梦数据库DM8、JDK安装、Nginx安装、vsftpd安装、硬盘挂载一件安装脚本
java·linux·数据库·nginx·kylin
rafael(一只小鱼)26 分钟前
gemini使用+部署教程
java·人工智能·ai·go
别动哪条鱼30 分钟前
AVFrame的data数组数据结构详解
网络·数据结构·ffmpeg