通过上一篇文章对顺序栈做了介绍,线性表分为顺序表和链表两种,与此相似,栈也分为顺序栈和链栈。
链栈与顺序栈外在的功能看起来以前,符合栈顶基本性质LIFO,但是在内部实现原理上我想大家一定从名称上就能够区分开,顺序栈元素之间的物理地址是相邻的,而链栈元素之间的物理地址再逻辑上是相邻的,链栈存在空栈的情况,但是不存在溢出(只要内存足够大),也就是说链栈的大小是没有限制的。实现链式栈和顺序栈的操作都是需要常数时间,即时间复杂度为O(1),主要从空间和时间两个方面考虑。
初始是,顺序栈需要事先声明顺序栈的长度,当堆栈不满时,造成了一定空间上的浪费,而链式栈的长度可变且长度不需要事先声明,相对比较节省空间,但是在每个节点中设定了一个指针域,从而产生了结构开销。当需要多个堆栈共享时,顺序存储中可以充分利用顺序栈的单向延伸性,可以使用一个数组存储两个堆栈,使每个堆栈从各自的端点向中间延伸,这样浪费的空间就会减少,但只有两个堆栈之间有相反的需求时才会有效,反之则会出现堆栈溢出。但是如果存在多个堆栈共享空间,其中一个共享栈满的时候其他共享栈可能还没有满,这样就需要将满栈中的元素向右或向左平移,这个过程会造成比较大的时间开销。
共享栈
链式栈的java实现:
public class LinkStack {
private Node top;
/**
* 构造方法
* */
public LinkStack(){
top = new Node();
}
/**
* 清空操作
* */
public void clear(){
top = new Node();
}
/**
* 压栈操作
* */
public void push(Object object){
Node node = new Node();
node.setObject(object);
node.setNext(top.getNext());
top.setNext(node);
}
/**
* 出栈操作
* */
public Node pop(){
if(top.getNext() == null){
System.out.println("Stack is Empty!");
return null;
}
Node returnNode = top.getNext();
top.setNext(top.getNext().getNext());
return returnNode;
}
/**
* 判断为空
* */
public boolean isEmpty(){
return (top.getNext() == null) ? true : false;
}
}
class Node {
private Object object;
private Node next;
public Node(){
this.next = null;
this.object = null;
}
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}