1、如何理解栈
比如我们在放盘子的时候都是从下往上一个个放,拿的时候是从上往下一个个的那,不能从中间抽,这种其实就是一个典型的栈型数据结构。后进先出即Last In First Out (LIFO)。
2、如何实现
其实它是一个限定仅在表尾进行插入和删除操作的线性表。 这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
栈其实就是一个特殊的链表或者数组。
既然栈也是一个线性表,那么我们肯定会想到数组和链表,而且栈还有这么多限制,那为什么我们还要使用这个数据结构呢?不如直接使用数组和链表来的更直接么?数组和链表暴露太多的接口,实现上更灵活了,有些技术理解不到位的人员就可能出错。所以在某些特定场景下最好是选择栈这个数据结构。
3、栈的分类
- 基于数组的栈——以数组为底层数据结构时,通常以数组头为栈底,数组头到数组尾为栈顶的生长方向
- 基于单链表的栈——以链表为底层的数据结构时,以链表头为栈顶,便于节点的插入与删除,压栈产生的新节点将一直出现在链表的头部
区别:最大的区别就是扩容,链表天然支持动态扩容。
4、基于数组的实现
public class MyStack {
private int[] elements;
public MyStack() {
this.elements = new int[0];
}
//显示所有元素
public void show() {
System.out.println(Arrays.toString(elements));
}
public void push(int element) {
int[] newArr = new int[elements.length + 1];
for (int i = 0; i < elements.length; i++) {
//把老数组复制到新的数组内
newArr[i] = elements[i];
}
newArr[elements.length] = element;
elements = newArr;
}
public int pop() {
int[] newArr = new int[elements.length - 1];
int result = elements[elements.length - 1];
for (int i = 0; i < elements.length - 1; i++) {
newArr[i] = elements[i];
}
elements = newArr;
return result;
}