栈和队列笔记2025-10-12

一.栈

1.核心方法的实现

1.1 核心方法
  • push(E e):元素入栈26
  • pop():移除并返回栈顶元素26
  • peek():查看栈顶元素但不移除26
  • isEmpty():判断栈是否为空

自己实现一遍栈的一些基本方法,印象比较深刻

我使用了ArrayList去实现这个栈,但你们也可以自己定义一个数组去实现(效果更好);

下面的代码是定义一个数组去实现一个栈:

java 复制代码
public class MyStack2 {
    int[] array;
    int size;//用来记录栈内有效数据
    public MyStack2() {
        //初始化数组
        array = new int[5];
    }
    public int push(int val) {
        //1.判断是否放得下
        if(isFull()) {
            //扩容
            addCapacity();
        }
        array[size++] = val;
        return val;
    }
    //判断栈是否满了
    public boolean isFull() {
        return size == array.length;
    }
    //扩容
    private void addCapacity() {
        array = Arrays.copyOf(array,size*2);
    }
    public int pop() {
        //1.判空
        if(isEmpty()) {
            throw new IsEmptyException("栈为空!!无法删除!!!");
        }
        int temp = array[size-1];
        size--;
        return temp;
    }
    //判空
    public boolean isEmpty() {
        return size == 0;
    }
    public int peek() {
        return array[size-1];
    }
    public int size() {
        return size;
    }
}

1.2下面是我在实现过程中出现的问题:

我在使用ArrayList的时候,没有去初始化,导致出现空指针异常!!!

1.3 方法展示

java 复制代码
public class MyStack {
    private ArrayList<Integer> stack = new ArrayList<>();

    // 1. Push方法增加元素(头增)
    public void push(int val) {
        stack.add(val);
    }

    // 2. Pop方法删除元素(尾删)
    public int pop() {
        if (isEmpty()) {
            throw new IsEmptyException("空栈!!无法删除!!");
        }
        int temp = stack.remove(stack.size() - 1);
        return temp;
    }

    // 3. 检验是否为空
    public boolean isEmpty() {
        return stack.isEmpty();
    }

    // 4. 获取栈顶元素
    public int peek() {
        if (isEmpty()) {
            throw new IsEmptyException("空栈!!");
        }
        return stack.get(stack.size() - 1);
    }

    // 5. 获取有效元素
    public int size() {
        return stack.size();
    }
}

可以自己动手写写,才会发现问题

2.习题

2.1 逆序打印链表

2.1.1 递归

对于逆序打印链表,我们最先想到的方法是用递归的方法,利用递归的特点来实现逆序打印,如下图:

接下来是代码实现

java 复制代码
public void printList(Node head) {
        //递归条件
        if(head != null) {
            printList(head.next);
            System.out.println(head.val +" ");
        }
    }
2.1.2 循环

我们接下来利用栈的先进后出的特性来实现链表的逆序打印;

java 复制代码
public void printList(Node head) {
        //1.判空
        if(head == null) {
            return;
        }
        //2.定义一个栈
        Stack<Node> stack = new Stack<Node>();
        //3.将链表中的结点保存在栈中
        Node cur = head;
        while(cur != null) {
            stack.push(cur);
            cur = cur.next;
        }
        //4.逐一出栈
        while(!stack.isEmpty()) {
            System.out.println(stack.pop().val + " ");
        }
    }

2.2 括号匹配

2.2.1题目描述:

20. 有效的括号 - 力扣(LeetCode)(题目的链接,有需要可以直接点进去)

给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。
2.2.2 题解:(下面是我自己写的可能会有点繁琐,大家如果解出来了,可以在评论区分享一下)
java 复制代码
public static boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();
        for(int i = 0; i < s.length(); i++) {
            //拿到每一个括号
            char ch = s.charAt(i);
            //判断是否是左括号
            if (left(ch)) {
                //入栈
                stack.push(ch);
            }
            if(stack.isEmpty()) {
                return false;
            }
            if(rigth(ch)) {
                //右括号匹配
                switch (ch){
                    case '}':
                        if(stack.peek() == '{') {
                            stack.pop();
                        }else {
                            return false;
                        }
                        break;
                    case ']':
                        if(stack.peek() == '[') {
                            stack.pop();
                        }else {
                            return false;
                        }
                        break;
                    case ')':
                        if(stack.peek() == '(') {
                            stack.pop();
                        }else {
                            return false;
                        }
                        break;

                }
            }
        }
        if(!stack.isEmpty()) {
            return false;
        }
        return true;
    }
    public static boolean rigth(char ch) {
        if(ch == ']' ||ch == ')' ||ch == '}' ) {
            return true;
        }
        return false;
    }
    public static boolean left(char ch) {
        if(ch == '[' ||ch == '(' ||ch == '{' ) {
            return true;
        }
        return false;
    }

2.3 栈的压入,弹出顺序

2.3.1 题目描述:

栈的压入、弹出序列_牛客题霸_牛客网(题目的链接,有需要可以直接点进去)

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。

  1. 0<=pushV.length == popV.length <=1000

  2. -1000<=pushV[i]<=1000

  3. pushV 的所有数字均不相同

2.3.2 题解:(这题思路很简单,但真正实现起来很难,记得画图辅助思考)
java 复制代码
public static boolean IsPopOrder (int[] pushV, int[] popV) {
        //1.定义一个栈
        Stack<Integer> stack = new Stack<>();
        int j = 0;
        for (int i = 0; i < pushV.length; i++) {
            stack.push(pushV[i]);
            while(!stack.isEmpty() && j < popV.length && stack.peek() == popV[j]) {
                j++;
                stack.pop();
            }
        }
        
        return stack.isEmpty();
    }

那我们的栈就先讲到这里~~其实还有两个习题没补充完~~

相关推荐
论迹14 小时前
【JavaEE】-- Cookie &&Session
java·java-ee
zhangrelay14 小时前
如何使用AI快速编程实现标注ROS2中sensor_msgs/msg/Image图像色彩webots2025a
人工智能·笔记·opencv·学习·计算机视觉·机器人视觉
czhc114007566314 小时前
Java114 LeeCode 翻转二叉树
java
m0_5982500014 小时前
电源完整性07-如何确定PDN网络中的大电容
笔记·单片机·嵌入式硬件·硬件工程
一 乐14 小时前
个人理财系统|基于java+小程序+APP的个人理财系统设计与实现(源码+数据库+文档)
java·前端·数据库·vue.js·后端·小程序
盖世英雄酱5813615 小时前
java深度调试技术【第四五章:多线程和幽灵代码】
java·后端
稚辉君.MCA_P8_Java15 小时前
深入理解 TCP;场景复现,掌握鲜为人知的细节
java·linux·网络·tcp/ip·kubernetes
熊猫比分站15 小时前
[特殊字符] Java/Vue 实现体育比分直播系统,支持多端实时更新
java·开发语言·vue.js
lang2015092815 小时前
深入掌握 Maven Settings:从配置到实战
java·maven
scx_link15 小时前
修改JetBrains产品(IntelliJ IDEA 、PyCharm等软件)的默认插件和日志的存储位置
java·pycharm·intellij-idea