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

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

相关推荐
404未精通的狗4 小时前
(数据结构)线性表(下):链表分类及双向链表的实现
数据结构·链表
java坤坤4 小时前
Spring Boot 集成 SpringDoc OpenAPI(Swagger)实战:从配置到接口文档落地
java·spring boot·后端
Uluoyu4 小时前
word、pdf文档内容提取工具类
java·pdf·word
自由的疯4 小时前
java 怎么判断事务有无提交成功
java·后端·架构
流星白龙4 小时前
【Qt】3.认识 Qt Creator 界面
java·开发语言·qt
机灵猫4 小时前
深入理解 Java 类加载与垃圾回收机制:从原理到实践
java·开发语言
Sunsets_Red4 小时前
差分操作正确性证明
java·c语言·c++·python·算法·c#
QZ_orz_freedom4 小时前
学习笔记--文件上传
java·笔记·学习
焰火19994 小时前
[Java][SpringBoot]集成Redis实现Session共享
java·redis