【数据结构_8】栈和队列

一、反向输出链表元素

Ⅰ使用递归进行反向输出

java 复制代码
package stack;
public class Test2 {
    static class Node{
       public String val;
       public  Node next;

        //构造方法
        public Node(String val) {
            this.val = val;
            this.next = null;
        }
    }
    //利用递归来反向输出链表
    public static void reverse(Node head){
        if (head == null){
            return;
        }
        reverse(head.next);
        System.out.print(head.val+"  ");
    }
    public static Node build(){
        Node a = new Node("a");
        Node b = new Node("b");
        Node c = new Node("c");
        Node d = new Node("d");
        a.next = b;
        b.next= c;
        c.next =d ;
        return a;
    }
    public static void main(String[] args) {
        Node head = build();
        reverse(head);
    }
}

Ⅱ利用栈进行链表元素的反向输出

java 复制代码
package stack;

import java.util.Stack;

public class Test2 {
    static class Node{
       public String val;
       public  Node next;

        //构造方法
        public Node(String val) {
            this.val = val;
            this.next = null;
        }
    }
    //利用栈来进行反向输出
    public static void reversePrint(Node head){
        //创建栈
        Stack<Node> stack = new Stack<>();//栈里面放的应该是节点,之后打印才可以通过节点引出他门的val
     //1.首先判断特殊情况
     if(head== null){return;}
     //把链表元素进行入栈操作
        for(Node cur = head;cur!= null;cur = cur.next){
            stack.push(cur);
        }
        while(!stack.isEmpty()){
            System.out.print(stack.pop().val);
        }

    }
    public static Node build(){
        Node a = new Node("a");
        Node b = new Node("b");
        Node c = new Node("c");
        Node d = new Node("d");
        a.next = b;
        b.next= c;
        c.next =d ;
        return a;
    }
    public static void main(String[] args) {
        Node head = build();
        reversePrint(head);
    }
}

三、有关stack的oj题

解题思路:

1.准备栈并且遍历字符串中的每个字符

2.如果发现当前字符是左括号,就直接入栈

3.如果发现当前字符是右括号,取出刚才的栈顶元素,用当前的右括号和栈顶左括号去判定匹配

如果是配对就继续往下遍历

如果不配对,返回false

java 复制代码
class Solution {
    public boolean isValid(String s) {
        //首先创建一个栈 这个栈用来存放字符 所以类型选用的是Character
        Stack<Character> stack = new Stack<>();
        //然后进行入栈操作
        for(int i =0 ;i<s.length();i++){
            char c = s.charAt(i);
            //如果是左括号就入栈
            if(c=='['||c=='('||c=='{'){
                stack.push(c);
                continue;
            }
            //如果是右括号,就进行判定括号匹配
            if(c==']'||c==')'||c=='}'){
                //取出栈顶元素
                //如果栈为空,无法取到栈顶
                //由于当前读到了一个右括号,要求必须得在栈里面有一个匹配的左括号
                //但是栈是空的,说明没有匹配的左括号,那么直接返回false
                if(stack.isEmpty()){
                    return false;
                }
                //取出栈顶元素
                char top = stack.pop();
                if(top =='['&& c==']'){
                    continue;
                }
                if(top =='('&&c==')'){
                    continue;
                }
                if(top =='{'&& c =='}'){
                    continue;
                }
                //其他情况,匹配失效
                return false;
            }
        }
        //整个循环结束,再来检查栈是否为空
        //如果栈为空,说明所有括号都匹配成功
        //如果栈不为空,说明还有未匹配的左括号
        if(stack.isEmpty()){
            return true;
        }
        return false;
    }
}
java 复制代码
class Solution {

    public static Boolean isNum(String token){
        //如果token是运算符,就返回false,否则就返回true
        if(token.equals("+")||token.equals("-")||token.equals("*")||token.equals("/")){
            return false;
        }
        return true;
    }

    public int evalRPN(String[] tokens) {
        //1.准备一个栈,用来存放操作数
        Stack<Integer> stack = new Stack<>();
        //2.遍历tokens,取出每个元素
        for(String token:tokens){
            //3.判断token是数字
            if(isNum(token)){
                //直接入栈
                stack.push(Integer.parseInt(token));
                continue;
            }
            //4.判定token是运算符
            //出栈两个元素,先出栈的是第二个操作数,后出栈的是第一个操作数
            int num2 = stack.pop();
            int num1 = stack.pop();
            //5.判定当前的运算符是哪个并且进行运算把得到的结果重新入栈
            if(token.equals("+")){
                stack.push(num1+num2);
            }else if(token.equals("-")){
                stack.push(num1-num2);
            }else if(token.equals("*")){
                stack.push(num1*num2);
            }else if(token.equals("/")){
                stack.push(num1/num2);
            }
        }
        //最终整个表达式的结果就是栈里的唯一一个元素
        return stack.pop();
    }
}

解题思路:1.先有一个栈

2.遍历pushA,把每个元素,依次出栈

3.在每次入栈一个元素之后,都拿着popA进行判定

a)检测栈是否未空

b)如果栈不为空,判定栈顶元素是不是等于popA的当前元素

c)如果发现符合上述要求

出栈,并且增加popA的下标

出栈成功,回到(a)继续循环处理

d)如果不符合上述要求,回到2.继续遍历下一个pushA元素

4.pushA遍历完毕之后,如果栈为空,说明当前的结果就是true,如果栈不为空,说明结果就是false。

java 复制代码
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pushV int整型一维数组 
     * @param popV int整型一维数组 
     * @return bool布尔型
     */
    public boolean IsPopOrder (int[] pushV, int[] popV) {
        // write code here
        //1.准备一个栈
     Stack<Integer> stack = new Stack<>();
     //2.针对pushV进行遍历
     int pushIndex =0;
     int popIndex = 0;
     for(;pushIndex <pushV.length;pushIndex++){
        //3.把当前的pushIndex指向的元素入栈
        stack.push(pushV[pushIndex]);
        //4.拿着popV的当前元素和栈顶进行比较,循环比较的过程,只要比较成功就出栈,并且进行下次循环
        //也就是比较popA的下一个元素和栈顶的元素
        while(!stack.isEmpty() && stack.peek()==popV[popIndex]){
            stack.pop();
            popIndex++;
        }
        //上述条件不匹配,说明当前popIndex指向的元素和栈顶元素是不一样的
        //此时就需要再次入栈新的元素找新的机会
        //此处结束循环进入下次即可
     }
    //5.当中整个pushA遍历完毕,说明"所有的机会"都用完了
    //此时如果栈已经是空了,说明前面popA的元素就都匹配成功;如果栈非空,还有popA的元素是无法匹配的
    if(stack.isEmpty()){
        return true;
    }
    return false;
    }
}
java 复制代码
class MinStack {
    private Stack<Integer> stack1 = new Stack<>();
    private Stack<Integer> stack2 = new Stack<>();

    public MinStack() {
        // 这个方法空着就行了, 不需要.
    }

    public void push(int val) {
        // stack1 就是正常入栈.
        stack1.push(val);
        // 针对 stack2, 就需要比较 val 和 stack2 栈顶元素的大小, 把小的元素入栈.
        if (stack2.isEmpty()) {
            // 如果 stack2 栈为空, 直接入栈.
            stack2.push(val);
            return;
        }
        int min = stack2.peek();
        if (val < min) {
            stack2.push(val);
        } else {
            stack2.push(min);
        }
    }

    public void pop() {
        if (stack1.isEmpty()) {
            // 在做 OJ 题的时候, 不要抛出异常.
            return;
        }
        // 把这两个栈的元素都出栈.
        stack1.pop();
        stack2.pop();
    }

    public int top() {
        // 取正常的栈顶元素.
        if (stack1.isEmpty()) {
            // 由于不是 Integer, 无法返回 null. 而且右不能修改人家方法的返回值类型. 此处就返回 0 .
            return 0;
        }
        return stack1.peek();
    }

    public int getMin() {
        // 取 stack2 栈顶元素.
        if (stack2.isEmpty()) {
            return 0;
        }
        return stack2.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();
 */
相关推荐
Scott9999HH1 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
腻害兔2 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社2 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海3 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖3 小时前
JDK 26 新特性详解
java·开发语言
马优晨4 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区6 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大6 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai7 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
维天说7 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json