栈和队列笔记2025-10-12
一.栈
1.核心方法的实现
1.1 核心方法
push(E e)
:元素入栈26pop()
:移除并返回栈顶元素26peek()
:查看栈顶元素但不移除26isEmpty()
:判断栈是否为空
自己实现一遍栈的一些基本方法,印象比较深刻
我使用了ArrayList去实现这个栈,但你们也可以自己定义一个数组去实现(效果更好);
下面的代码是定义一个数组去实现一个栈:
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 方法展示
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 递归
对于逆序打印链表,我们最先想到的方法是用递归的方法,利用递归的特点来实现逆序打印,如下图:
接下来是代码实现
public void printList(Node head) {//递归条件if(head != null) {printList(head.next);System.out.println(head.val +" ");}}
2.1.2 循环
我们接下来利用栈的先进后出的特性来实现链表的逆序打印;
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
,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
2.2.2 题解:(下面是我自己写的可能会有点繁琐,大家如果解出来了,可以在评论区分享一下)
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 题解:(这题思路很简单,但真正实现起来很难,记得画图辅助思考)
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();}
那我们的栈就先讲到这里~~其实还有两个习题没补充完~~