栈及其Java实现
栈(Stack)又名堆栈,是允许在同一端进行插入和删除操作的特殊线性表。其中,允许进行插入和删除操作的一端叫做栈顶(Top),另一端叫做栈底(Bottom),栈底固定,栈顶浮动。在栈中的元素个数为零时,该栈叫做空栈。插入的过程叫做进栈(Push),删除的 过程叫作退栈(Pop)。栈也叫作后进先出(FILO-First In Last Out)的线性表。具体的数据结构图如图所示。
要实现一个栈,需要先实现如下核心方法。
push():向栈中压入一个数据,先入栈的数据在最下边。
pop():弹出栈顶数据,即移除栈顶数据。
peek():返回当前的栈顶数据。
栈的具体实现过程如下。
(1)定义栈的数据结构:
/**
* 基于数组实现的顺序栈
* @param <E>
*/
public class Stack<E> {
private Object[] data = null;
private int maxSize = 0; // 栈的最大容量
private int top = -1; //栈顶的指针
//构造函数:根据指定的size初始化栈
Stack() {
this(10); //默认栈的大小为10
}
Stack (int initialSize) {
if (initialSize >= 10) {
this.maxSize = initialSize;
data = new Object[initialSize];
top = -1;
} else {
throw new RuntimeException("初始化大小不能小于0:" + initialSize);
}
}
}
以上代码定义了一个Stack类,用于存储栈的数据结构;定义了一个数组data,用于存储栈中的数据;定义了一个变量maxSize,表示栈的最大容量;定义了一个变量top,表示栈顶的指针;定义了两个栈的构造函数,在构造函数没有参数时默认构造一个大小为10的栈。
(2)数据入栈,向栈顶压入一个数据:
//进栈,第1个元素top=0
public boolean push(E e) {
if(top == maxSize - 1) {
throw new RuntimeException("栈已满,无法将元素入栈!");
} else {
data[++top] = e;
return true;
}
}
以上代码定义了push方法来向栈中压入数据,在数据入栈前首先判断栈是否满了,具体的判断依据为栈顶元素的指针位置等于栈的最大容量。注意,这里使用maxSize-1是因为栈顶元素的指针是从0开始计算的。在栈有可用空间时,使用data[++top]=e在栈顶(top位置)上方新压入一个元素并将top加1.
(3)数据出栈,从栈顶移除一个数据:
//弹出栈顶的元素
public E pop() {
if(top == -1) {
throw new RuntimeException("栈为空!");
} else {
return (E)data[top--];
}
}
以上代码定义了pop方法来从栈顶移除一个数据,在移除前先判断栈顶是否有数据,如果有,则通过data[top–]将栈顶数据移除并将top减1.
(4)查询数据:
//查询栈顶元素但不移除
public E peek() {
if (top == -1) {
throw new RuntimeException("栈为空!");
} else {
return (E)data[top];
}
}
以上代码定义了peek方法来取出栈顶的数据,在取出栈顶的数据前先判断栈顶的元素是否存在,如果存在,则直接返回栈顶的元素,否则抛出异常。
测试样例:
public static void main(String[] args) {
Stack<Integer> element = new Stack<Integer>(15);
for (int i = 0 ; i < 15 ; i++) {
element.push(i);
}
System.out.println(element.pop());
System.out.println(element.peek());
}