1. 隊列的定義
隊列是一種特殊的線性表,它包含一個隊頭(front)和一個隊尾(rear),其中隊頭只允許刪除元素,隊尾只允許插入元素。隊列的特定是先進入隊列的元素先出來,即先進先出(FIFO)。出隊列時,只有當前面的元素都退出之後,後面的元素才能退出。
圖 隊列示意圖
2. 隊列的操作
隊列的主要操作有下面6種:
(1)InitQueue(&Q):初始化操作,獨立一個空隊列Q。
(2)QueueEmpty(Q):若Q為空白隊列,返回1,否則返回0。
(3)EnterQueue(&Q,x):插入元素X到隊列Q的隊尾。
(4)DeleteQueue(&Q,&e):刪除Q的隊首元素,並用e返回其值。
(5)Gethed(Q,&e):用e返回Q的隊首元素。
(6)ClearQueue(&Q):將隊列Q清空。
3. 隊列的順序儲存
隊列有兩種儲存方式:順序儲存和鏈式儲存。採用順序儲存結構的隊列稱為順序隊列,採用鏈式儲存結構的隊列稱為鏈式隊列。
鏈式隊列通常採用一維數組進行儲存。其中,連續的儲存單元一次存放隊列中的元素。同時,使用兩個指標分別表示數組中存放的第一個元素和最後一個元素的位置。其中,指向第一個元素的位置指標稱為隊頭指標front,指向最後一個元素位置的指標稱為隊尾指標rear。
順序隊列的類型定義如下: C代碼 #define QueueSize 40 /* 隊列的容量 */ typedef struct Squeue{ DataType queue[QueueSize]; int front,rear; /* 隊頭指標和隊尾指標 */ }SeqQueue;
順序隊列會出現“真溢出”和“假溢出”現象。所謂“真溢出”是指插入元素已超過分配的儲存空間,不能再繼續插入元素;而“假溢出”是指隊尾指標已經達到數組的尾端,而隊頭指標之前有刪除元素後留下的剩餘空間,這是經過多次插入和刪除操作引起的,像這種有儲存空間而不能再進行插入元素操作的溢出稱為“假溢出”。
圖 假溢出示意圖
為了避免順序隊列造成“假溢出”現象,通常採用順序迴圈隊列來實現隊列的順序儲存。為了充分利用儲存空間,消除“假溢出”現象,就是當隊尾指標rear和隊頭指標front到達儲存空間的最大值QueueSize時,讓隊尾指標和隊頭指標自動轉化為儲存空間的最小值0。這樣就把順序隊列使用的儲存空間構造成一個邏輯上首尾相連的迴圈隊列。注意:順序迴圈隊列中的入隊操作和出隊操作都要模數,確保操作不出界。
圖 順序迴圈隊列
4. 隊列的鏈式儲存
為了避免順序隊列在進行插入和刪除操作時大量移動元素,可以採取鏈式儲存結構表示隊列。一個鏈式隊列通常採用鏈表實現。其中,鏈表包括兩個域:資料域和指標域。資料域用來存放隊列中的元素,指標域用來存放隊列中下一個元素的地址。同時,使用兩個指標分別指示鏈表中存放的第一個元素和最後一個元素的位置。其中,指向第一個元素位置的指標稱為隊頭指標front,指向最後一個元素的位置的指標稱為隊尾指標rear。
鏈式隊列的類型定義如下: C代碼 /* 節點類型定義 */ typedef struct QNode { DataType data; struct QNode* next; }LQNode, *QueuePtr; /* 隊列類型定義 */ typedef struct { QueuePtr front; QueuePtr rear; }LinkQueue;
圖 鏈式隊列示意圖
5. 雙端隊列
雙端隊列是一種特殊的隊列,它是線上性表的兩端對插入和刪除操作限制的線性表。雙端隊列可以再隊列的任何一端進行插入和刪除操作,而一般的隊列要求在一端插入元素,另一端刪除元素。
輸入受限的雙端隊列:線性表的兩端都可以輸出資料元素,但是只能在一端輸入資料元素。
輸出受限的雙端隊列:線性表的兩端都可以輸入資料元素,但是只能在一端輸出資料元素。
圖 雙端隊列示意圖