一.栈

1.核心方法的实现
1.1 核心方法
push(E e)
:元素入栈26pop()
:移除并返回栈顶元素26peek()
:查看栈顶元素但不移除26isEmpty()
:判断栈是否为空
自己实现一遍栈的一些基本方法,印象比较深刻
我使用了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
,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
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就不可能是该压栈序列的弹出序列。
-
0<=pushV.length == popV.length <=1000
-
-1000<=pushV[i]<=1000
-
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();
}
那我们的栈就先讲到这里~~其实还有两个习题没补充完~~