1.栈模型定义
- 栈(stack)是根据插入和删除只能在一个位置上进行的表,该位置在表的末端,叫做栈的顶(top)。也就是说栈结构是一种后进先出(LIFO)的表。
- 对栈的基本操作有push(进栈)和pop(出栈),push操作是插入新元素,而pop则是删除最后插入的元素。
- 对空栈进行的pop一般被认为是栈ADT中的一个错误。当运行push时空间用尽是一个实现限制,但不是ADT错误。
栈的结构如下图:
2.栈的实现
由于栈是一个表,因此任何可以实现表的方法都能实现栈。也就是说数组和链表都支持栈操作,而99%的时间他们都是最合理的选择,因为栈操作是常数时间O(1),所以除非在非常独特的环境下,这是不可能产生任何明显的改进的。
栈的链表实现思路:
在栈中使用top指向栈顶,每次进行push操作时,将top指向这个新进入的元素,而这个新元素的next指针指向之前的栈顶元素,就形成了一个链表结构的栈。出栈时,将top指向top.next,将top之前指向的元素返回给调用者。
代码:
//栈结构定义:
interface Stack<T> {
void push(T element);//压栈
T pop();//出栈
boolean isEmpty();
int size();
//使用链表的形式实现
public class LinkedStack<T> implements Stack<T> {
//栈结构中数据节点定义:
private class LinkedNode<T> {
private T element;
public LinkedNode next;
public LinkedNode(T element) {
this.element = element;
}
public T getElement() {
return this.element;
}
}
private LinkedNode top; //指向栈顶
private int count;//标记栈的大小
public TestStack() {
top = null;
count = 0;
}
public int size() {
return count;
}
public boolean isEmpty() {
return (size() == 0);
}
public void push(T element) {
LinkedNode<T> node = new LinkedNode<T>(element);
node.next = top;
top = node;
count++;
}
public T pop() {
if(isEmpty())
{
System.out.println("stack is empty!");
System.exit(1);
}
top = top.next;
count--;
return (T)top.getElement();
}
}
3.栈的应用
- 平衡符号
- 后缀表达式
- 方法调用