栈和队列笔记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();
    }

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

相关推荐
雨中飘荡的记忆4 小时前
ElasticJob分布式调度从入门到实战
java·后端
考虑考虑12 小时前
JDK25模块导入声明
java·后端·java ee
_小马快跑_13 小时前
Java 的 8 大基本数据类型:为何是不可或缺的设计?
java
Re_zero16 小时前
线上日志被清空?这段仅10行的 IO 代码里竟然藏着3个毒瘤
java·后端
洋洋技术笔记16 小时前
Spring Boot条件注解详解
java·spring boot
程序员清风1 天前
程序员兼职必看:靠谱软件外包平台挑选指南与避坑清单!
java·后端·面试
皮皮林5511 天前
利用闲置 Mac 从零部署 OpenClaw 教程 !
java
华仔啊2 天前
挖到了 1 个 Java 小特性:var,用完就回不去了
java·后端
SimonKing2 天前
SpringBoot整合秘笈:让Mybatis用上Calcite,实现统一SQL查询
java·后端·程序员
日月云棠2 天前
各版本JDK对比:JDK 25 特性详解
java