Java数据结构之栈:特性、应用与LeetCode实战详解

Hazel
Hazel
发布时间:2026-10-13 | 5人浏览过
原创

本文深入解析Java中栈数据结构的特性与常用方法,包括入栈、出栈及判空操作。重点探讨栈在括号匹配、后缀表达式求值、队列模拟及最小栈等场景的应用,结合LeetCode经典题目提供完整代码实现与逻辑分析,帮助开发者掌握栈的核心用法。

一、栈

栈是一种遵循先进后出(LIFO)原则的线性数据结构。其核心操作包括:入栈(push),即将元素压入栈顶;出栈(pop),即移除并返回栈顶元素;判断栈是否为空(empty);以及查看栈顶元素(peek),该操作不移除元素。

1.栈的应用

1.1括号匹配

 public boolean isValid(String s) {
        //有效括号时隔4个月后重新打卡 看看栈学的怎么样
        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.empty()){
                   //右括号多
                   return false;
               }else{
                   char ch1=stack.peek();
                   if(ch1=='{'&&ch=='}'||ch1=='['&&ch==']'||ch1=='('&&ch==')'){
                       stack.pop();
                   }else{
                       return false;
                   }
               }
           }
       }
       if(!stack.empty()){
           return false;
       }
       return true;
    }

1.2后缀表达式

我们日常接触最多的表达式形式如 a+b,这被称为中缀表达式。

前缀表达式(波兰表达式)将运算符置于操作数之前,例如 +ab。

后缀表达式(逆波兰表达式)将运算符置于操作数之后,例如 ab+。

将中缀表达式转换为后缀表达式的规则是:首先给表达式加上括号以明确运算优先级,然后将运算符移至对应括号的外侧,转换顺序遵循先乘除后加减的原则。

逆波兰表达式求值基于后缀表达式的特性:减法与除法中,后出栈的操作数作为被减数或被除数,先出栈的作为减数或除数。利用栈结构可以高效实现后缀表达式的计算逻辑。

public int evalRPN(String[] tokens) {
        Stack <Integer> stack=new Stack<>();
        int num1=0;
        int num2=0;
        for(String str:tokens){
            if(str.equals("+")){
                num1=stack.pop();
                num2=stack.pop();
                stack.push(num1+num2);
            }else if(str.equals("-")){
                num1=stack.pop();
                num2=stack.pop();
                stack.push(num2-num1);
            }else if(str.equals("*")){
                num1=stack.pop();
                num2=stack.pop();
                stack.push(num1*num2);
            }else if(str.equals("/")){
                num1=stack.pop();
                num2=stack.pop();
                stack.push(num2/num1);
            }else{
                stack.push(Integer.parseInt(str));
            }
        }
        return stack.pop();
    }

1.3用栈实现队列

通过两个栈模拟队列的行为,需要实现队列的标准接口方法:push(入队)、pop(出队)、peek(获取队首元素)以及 empty(判断是否为空)。

class MyQueue {
    public Stack<Integer> stack1;
    public Stack<Integer> stack2;
    /** Initialize your data structure here. */
    public MyQueue() {
         stack1 =new Stack<>();
         stack2 =new Stack<>();
    }
    /** Push element x to the back of queue. */
    public void push(int x) {
        stack1.push(x);
    }
    /** Removes the element from in front of queue and returns that element. */
    public int pop() {
        if(stack2.empty()){
            while(!stack1.empty()){
                stack2.push(stack1.pop());
            }
        }
        return stack2.pop();
    }
    /** Get the front element. */
    public int peek() {
        if(stack2.empty()){
            while(!stack1.empty()){
                stack2.push(stack1.pop());
            }
        }
        return stack2.peek();
    }
    /** Returns whether the queue is empty. */
    public boolean empty() {
        return stack1.empty()&&stack2.empty();
    }
}
/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue obj = new MyQueue();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.peek();
 * boolean param_4 = obj.empty();
 */

1.4最小栈

class MinStack {
    //定义双栈来实现最小栈
    public   Deque<Integer> stack1;
    public   Deque<Integer> minStack;
    /** initialize your data structure here. */
    public MinStack() {
        stack1=new LinkedList<Integer>();
        minStack=new LinkedList<Integer>();
        minStack.push(Integer.MAX_VALUE);
    }
    public void push(int val) {
        stack1.push(val);
        minStack.push(Math.min(val,minStack.peek()));
    }
    public void pop() {
        stack1.pop();
        minStack.pop();
    }
    public int top() {
        return stack1.peek();
    }
    public int getMin() {
        return minStack.peek();
    }
}
/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack obj = new MinStack();
 * obj.push(val);
 * obj.pop();
 * int param_3 = obj.top();
 * int param_4 = obj.getMin();
 */

1.5栈的压入和弹出序列

题目要求:给定两个整数序列,第一个序列代表栈的压入顺序,第二个序列代表栈的弹出顺序。请判断第二个序列是否为该栈合法的弹出序列。

public boolean validateStackSequences(int []pushed,int []popped){
        Stack <Integer> stack=new Stack<>();
        int i=0;
        for(int num:pushed){
            stack.push(num);
            while(!stack.isEmpty()&&stack.peek()==popped[i]){
                i++;
                stack.pop();
            }
        }
        return stack.isEmpty();
    }

总结

本文到此结束,希望上述内容能为您提供帮助。欢迎持续关注本站,获取更多技术干货!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表