大二自学Java栈的实现:从定义原理到代码实现的踩坑总结
一、栈是什么
-
栈是一种“后进先出”(LIFO)的线性数据结构
-
只能在一端(栈顶)进行插入、删除、查看
-
另一端固定,叫栈底
二、栈的核心操作
1. push():入栈 / 压栈
- 把元素放到栈顶
- 先移动指针,再存数据
//入栈方法push
public void push(E e){
if(size == maxSize){//判断栈是否满了
System.out.println("Stack is full");
}
data[++top] = e;
//往栈内加入元素,data为数组++top先给top+1再执行操作,保证top再加入元素后仍然为栈顶元素
size++;//每存入一个元素,栈内容量-1,size+1
}
2. pop():出栈 / 弹栈
- 取出并删除栈顶元素
- 先取值,再移动指针
//出栈方法pop
public E pop(){
if(top == -1){
throw new EmptyStackException();
}
else{
return (E)data[top--];//这里top--是先返回取出的top元素,再将top指针-1
}
}
3. peek():查看栈顶
- 只看不删,返回栈顶元素
- 不改变栈结构
//查找返回top指针peek
public E peek(){
if(top == -1){
throw new EmptyStackException();//若为空栈,则抛出空栈异常
}
else{
return (E)data[top];//data为object类型,大转小需要强制转换,下同理
}
}
4. isEmpty():判断是否为空
- 栈空返回 true,否则 false
5. size():获取当前元素个数
三、数组实现栈的核心思路
- 成员变量
- data[] :存储元素的数组
- top :栈顶指针(初始 = -1,表示空栈)
- maxSize :栈最大容量
- push 入栈逻辑
1. 判断是否满栈 2. top++ 3. data[top] = 元素
- pop 出栈逻辑
1. 判断是否空栈 2. 先保存 data[top] 3. top-- 4. 返回保存的值
- peek 查看栈顶逻辑
- 直接返回 data[top]
- 不修改 top,不删除元素
- isEmpty 判空
- return top == -1;
四、关键细节
1. 入栈:先 top++,再存值 2. 出栈:先取值,再 top-- 3. peek ≠ pop:
- peek:只看不动
- pop:取出并删除 4. 数组栈是固定容量,满了不能再 push 5. 扩容:栈满时新建更大数组,复制原数据(进阶功能)
五、一句话总结栈
只能在栈顶操作,后进先出;push 进、pop 出、peek 看、isEmpty 判断空。
六、注意
注意点:注意要先import java.util.EmptyStackException ,这样空栈调用pop时会抛出明确的异常,比返回null更安全规范。
import java.util.EmptyStackException;//空栈异常
七、完整main方法代码展示
public static void main(String[] args) {
//实例化并命名栈stack,<Integer>是给这个泛型栈指定了具体的类型参数,相当于贴标签
MyStack<Integer> stack = new MyStack<>();
stack.push(1);//用上面新建的实例化对象stack来调用push方法
stack.push(2);
stack.push(3);
stack.push(4);
stack.push(5);
stack.push(6);
stack.push(7);
stack.push(8);
stack.push(9);
stack.push(10);
System.out.println(stack.size);//输出现在栈内大小
System.out.println(stack.data[9]);//输出top指针所指的位置(输出栈顶元素指针)
//运用Arrays类中的方法来输出所有栈,另外还能重新写方法printStatic()来完成这一操作
System.out.println(Arrays.toString(stack.data));
stack.peek();
System.out.println(stack.peek());
System.out.println("=======================");
System.out.println(stack.pop());//输出取出的栈顶元素
}