栈数据结构

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();
    }
}
相关推荐
毕设源码-朱学姐5 分钟前
【开题答辩全过程】以 高校图书馆管理系统为例,包含答辩的问题和答案
java
xie_pin_an7 分钟前
C++ 从入门到进阶:核心知识与实战指南
java·c++·算法
Wpa.wk7 分钟前
性能测试-初识性能测试基础(性能测试流程,计划等)
java·运维·经验分享·测试工具·性能测试
Python_Study202510 分钟前
制造业数据采集系统选型指南:从技术挑战到架构实践
大数据·网络·数据结构·人工智能·架构
小鸡脚来咯13 分钟前
Java 关键字面试解释指南
java
毕设源码-郭学长37 分钟前
【开题答辩全过程】以 高校图书推荐系统的设计与实现为例,包含答辩的问题和答案
java
主公不搬砖37 分钟前
Nacos 2.5.2 国产信创 kingbase适配
java·docker·nacos·信创·kingbase·国产适配
谷隐凡二1 小时前
Kubernetes Route控制器简单介绍
java·容器·kubernetes
Haooog1 小时前
RAG医疗问答系统
java·大模型·项目·rag
luming-021 小时前
报错解决:IDEA终端输出和CMD终端输出Maven版本不一致
java·缓存·bug·intellij-idea