下壓堆棧(鏈表實現)
前篇文章討論瞭如何用數組實現一個下壓棧 (能夠動態調整數組大小)的方式,本文接着討論用簡單鏈表實現棧的方式。
由於鏈表這種簡單的數據結構具有以下優點:
- 在頭結點插入快,不受集合數據規模限制
- 在頭結點刪除快,同樣與數據量多少無關
- 綜上,插入和刪除頭結點元素所需時間與集合的大小無關
基於鏈表以上的兩個優點,正好對應棧結構中的壓棧和出棧操作,結合一個變量N,保存棧的元素個數,可以完美實現棧結構,代碼如下:
import java.util.Iterator;
import java.util.Scanner;
/**
* @author zhangjinglong
* @date 2019-06-05-21:53
* 下壓堆棧(鏈表實現)
*/
public class Stack<Item> implements Iterable<Item> {
private Node first;//棧頂 (最近添加的元素)
private int N; //棧中元素數量
private class Node{//定義了 經典鏈表實現中 結點的嵌套類
Item item;//結點中存儲的數據值
Node next;//指向下個結點的鏈接
}
public boolean isEmpty(){//判斷棧是否爲空
return first==null;//Stack 對象初始化時默認爲null
//也可使用 return N==0 實現
}
public int size() {return N;}
public void push(Item item){//向棧頂添加元素
Node oldfirst=first;
first=new Node();
first.item=item;
first.next=oldfirst;
N++;
}
public Item pop(){//從棧頂刪除元素
Item item = first.item;
first=first.next;
N--;
return item;
}
public Iterator<Item> iterator(){
return new ListIterator();
}
private class ListIterator implements Iterator<Item>{//定義返回的迭代器
private Node current=first;//複製一份頭結點引用,初始化current
public boolean hasNext(){return current.next!=null;}
public void remove(){}
public Item next(){
Item item=current.item;//保留當前指向結點的值,用以返回
current=current.next;//指向下一結點
return item;
}
}
public static void main(String[] args) {
//Stack 測試用例
//創建一個棧並根據輸入的字符串指示壓入或彈出字符串
Stack<String> s=new Stack<>();
Scanner scanner= new Scanner(System.in);
while(true){
if(scanner.hasNext()){
String item=scanner.next();
if(item.equals("!")){// !表示終止輸入
break;
}else if( item.equals("-")){
if(s.isEmpty()){
System.out.println("the stack is empty!");
}else{
System.out.println(s.pop()+ " ");
}
}else{
s.push(item);
}
}
}
System.out.println("("+s.size()+ " left on stack)");
}
}