一、棧
棧是一種線性表,一種抽象數據類型,它只允許在一端進行插入或刪除操作。又叫做LIFO(後進先出)線性表。
棧的基本操作有入棧push和出棧pop,棧頂top指的是進行操作的一端。如圖,只有棧頂元素可以訪問。進棧次序為a1、a2、a3、a4、a5,出棧次序為a5、a4、a3、a2、a1

棧是受限的線性表,因此任何實現表的方法都能實現棧,主要就是順序棧和鏈棧。
使用數組存放棧的數據元素,設有一個頭指針top執行棧頂,初始時為top=0,順序棧的實現代碼:
進棧:先放在top+1
public void push(T item){
if(top >= capacity) return;
items[top] = item;
top ++;
}
出棧:先top-1再取
public T pop(){
if(top < 0) return null;
return (T) items[--top];
}
通常采用單鏈表實現,所有的操作都在表頭進行。棧節點為:
private class Node{
T item;
Node next;
}
鏈棧的實現代碼,有一個頭指針top,只能用top指針執行push、pop(插入刪除)
進棧:頭插法
public void push(T item){
Node old = top;
top = new Node();
top.item = item;
top.next = old;
count++;
}
出棧:取時只需把top節點指向下個節點即可
public T pop(){
T item = top.item;
top = top.next;
count--;
return item;
}
只在一端插入,另一端刪除的線性表,類似於日常的排隊,特性是先進先出FIFO。其中有兩個指針,頭指針head和尾指針tail,在tail插入,在head讀取。

使用數組,初始狀態時,head=tail=0;當tail==MaxSize時,並不能說明隊列滿了,當head指針為tail的前一個位置,此時隊列中只有一個元素,但沒滿,這時入隊出現上溢出,這時一種假溢出。
2.1.1 循環隊列
也稱環形隊列,環形緩沖區,臆造一個環狀的空間,當隊頭或隊首指針達到最大時,重置為零,可以使用取余運算實現,(也能不用取余)。
取余運算:
初始時,head = tail = 0; 隊首加1,head = (head + 1) % MaxSize; 隊尾加1,tail = (tail + 1) % MaxSize; 隊列長度,(tail + MaxSize - head) % MaxSize;
不使用取余:
以RingBuffer環形緩沖區為例,具體代碼在GitHub,其中入隊和出隊的代碼如下,沒使用取模運算,(對計算機來說,加1減1比取模簡單)
入隊:
public boolean put(T item){
int next = tail + 1;
if(next >= bufferSize){
next = 0;
}
if(next == head){
lost++;
return false;
}
rBuffer[next] = item;
tail = next;
return true;
}
出隊:
public T get(){
if(head == tail){
return null;
}
@SuppressWarnings("unchecked")
T item = (T) rBuffer[head];
rBuffer[head] = null;
if(++head >= bufferSize){
head = 0;
}
return item;
}
鏈隊列,使用一個帶有隊頭head和隊尾tail指針的單鏈表,在head讀取,在tail插入。節點類型如下:
private Node head; // 隊頭
private Node tail; // 隊尾
private class Node{ // 節點
T item;
Node next;
}
入隊:
public void enqueue(T item){
Node old = tail;
tail = new Node();
tail.item = item;
tail.next = null;
if(isEmpty()){
head = tail;
} else {
old.next = tail;
}
count++;
}
出隊:
public T dequeue(){
T res = head.item;
head = head.next;
if(isEmpty()){
tail = null;
}
count--;
return res;
}
源碼地址:https://github.com/cyhe/algorithm/tree/master/src/algo/linearlist/stack