1. 程式人生 > >佇列(queue)的定義,佇列的儲存結構

佇列(queue)的定義,佇列的儲存結構

佇列定義

佇列(queue )簡稱隊,它同堆疊一樣,也是一種運算受限的線性表,
其限制是僅允許在表的一端進行插入,而在表的另一端進行刪除。
在佇列中把插入資料元素的一端稱為 隊尾(rear) ),刪除資料元素的一端稱為 隊首(front) )。
向隊尾插入元素稱為 進隊或入隊,新元素入隊後成為新的隊尾元素;
從佇列中刪除元素稱為 離隊或出隊,元素出隊後,其後續元素成為新的隊首元素。
由於佇列的插入和刪除操作分別在隊尾和隊首進行,每個元素必然按照進入的次序離隊,
也就是說先進隊的元素必然先離隊,所以稱佇列為 先進先出表(First In First Out,簡稱FIFO)。


生活案例:排隊打飯,排隊進地鐵站,上地鐵
技術案例:多執行緒中就緒佇列和阻塞佇列


對於佇列的主要操作是入隊和出隊操作
 

public interface Queue {
    // 返回佇列的大小
    public int getSize();
 
    // 判斷佇列是否為空
    public boolean isEmpty();
 
    // 資料元素 e 入隊
    public void enqueue(Object e);
 
    // 隊首元素出隊
    public Object dequeue();
 
    // 取隊首元素
    public Object peek();
    
}       

佇列的儲存結構
    順序佇列
    
    方法1:使用陣列作為儲存結構:

  缺點:通過出隊操作將資料彈出佇列後,front之前的空間還能夠再次得到嗎?
        不能。所以使用普通陣列實現佇列,就再也不能使用front之前的空間了,這會導致大量空間丟失

    
    方法2:使用迴圈陣列作為儲存結構:    
    為了解決這個問題,將普通陣列換成迴圈陣列。在迴圈陣列中,末尾元素的下一個元素不是陣列外,而是陣列的頭元素。
    這樣就能夠再次使用front之前的儲存空間了

 鏈式佇列


    佇列的鏈式儲存可以使用單鏈表來實現。
    為了操作實現方便,這裡採用帶頭結點的單鏈表結構。
    根據單鏈表的特點,選擇連結串列的頭部作為隊首,連結串列的尾部作為隊尾。
    除了連結串列頭結點需要通過一個引用來指向之外,還需要一個對連結串列尾結點的引用,以方便佇列的入隊操作的實現。
    為此一共設定兩個指標,一個隊首指標和一個隊尾指標,如圖 所示。
    隊首指標指向隊首元素的前一個結點,即始終指向連結串列空的頭結點,隊尾指標指向隊列當前隊尾元素所在的結點。
    當佇列為空時,隊首指標與隊尾指標均指向空的頭結點

 

雙端佇列

 

deque  double ended queue  通常讀為“deck”
      
所謂雙端佇列是指兩端都可以進行進隊和出隊操作的佇列,如下圖所示,將佇列的兩端分別稱為前端和後端,兩端都可以入隊和出隊。其元素的邏輯結構仍是線性結構

在雙端佇列進隊時:前端進的元素排列在佇列中後端進的元素的前面,後端進的元素排列在佇列中前端進的元素的後面。在雙端隊列出隊時,無論前端出還是後端出,先出的元素排列在後出的元素的前面。

輸出受限的雙端佇列,即一個端點允許插入和刪除,另一個端點只允許插入的雙端佇列。 

輸入受限的雙端佇列,即一個端點允許插入和刪除,另一個端點只允許刪除的雙端佇列。