佇列,和棧一樣,也是一種對資料的"存"和"取"有嚴格要求的線性儲存結構。
與棧結構不同的是,佇列的兩端都"開口",要求資料只能從一端進,從另一端出,如下圖示:
通常,稱進資料的一端為 "隊尾",出資料的一端為 "隊頭",資料元素進佇列的過程稱為 "入隊",出佇列的過程稱為 "出隊"。不僅如此,佇列中資料的進出要遵循 "先進先出" 的原則,即最先進佇列的資料元素,同樣要最先出佇列。拿圖 1 中的佇列來說,從資料在佇列中的儲存狀態可以分析出,元素 1 最先進隊,其次是元素 2,最後是元素 3。此時如果將元素 3 出隊,根據佇列 "先進先出" 的特點,元素 1 要先出佇列,元素 2 再出佇列,最後才輪到元素 3 出佇列。
棧和佇列不要混淆,棧結構是一端封口,特點是"先進後出";而佇列的兩端全是開口,特點是"先進先出"。順序佇列,即採用順序表模擬實現的佇列結構。因此,資料從表的一端進,從另一端出,且遵循 "先進先出" 原則的線性儲存結構就是佇列。
我們知道,佇列具有以下兩個特點: 資料從佇列的一端進,另一端出; 資料的入隊和出隊遵循"先進先出"的原則;因此,只要使用順序表按以上兩個要求運算元據,即可實現順序佇列。首先來學習一種最簡單的實現方法。
由於順序佇列的底層使用的是陣列,因此需預先申請一塊足夠大的記憶體空間初始化順序佇列。除此之外,為了滿足順序佇列中資料從隊尾進,隊頭出且先進先出的要求,我們還需要定義兩個指標(top 和 rear)分別用於指向順序佇列中的隊頭元素和隊尾元素,如下圖所示:
由於順序佇列初始狀態沒有儲存任何元素,因此 top 指標和 rear 指標重合,且由於順序佇列底層實現靠的是陣列,因此 top 和 rear 實際上是兩個變數,它的值分別是隊頭元素和隊尾元素所在陣列位置的下標。
在上圖的基礎上,當有資料元素進佇列時,對應的實現操作是將其儲存在指標 rear 指向的陣列位置,然後 rear+1;當需要隊頭元素出隊時,僅需做 top+1 操作。
例如,在上圖的基礎上將用順序佇列儲存的實現操作如下圖所示:
在上圖基礎上,順序佇列中資料出佇列的實現過程如下圖所示:
因此,使用順序表實現順序佇列最簡單方法的 c 語言實現**為:
#include int enqueue(int *a,int rear,int data)
void dequeue(int *a,int front,int rear)
}int main()
程式輸出結果:
出隊元素:1 出隊元素:2 出隊元素:3 出隊元素:4此方法存在的問題先來分析上面兩張圖。第一張圖的b是有資料進隊成功的示意圖,而第二張圖的b 是所有資料全部出隊後的示意圖。通過對比兩張圖,你會發現,指標 top 和 rear 重合位置指向了 a[4] 而不再是 a[0]。也就是說,整個順序佇列在資料不斷地進隊出隊過程中,在順序表中的位置不斷後移。
順序佇列整體後移造成的影響是: - 順序佇列之前的陣列儲存空間將無法再被使用,造成了空間浪費; - 如果順序表申請的空間不足夠大,則直接造成程式中陣列 a 溢位,產生溢位錯誤;
為了避免以上兩點,我建議初學者使用下面的方法實現順序佇列。
既然明白了上面這種方法的弊端,那麼我們可以試著在它的基礎上對其改良。
為了解決以上兩個問題,可以使用巧妙的方法將順序表打造成乙個環狀表,如下圖所示:
上圖只是乙個想象圖,在真正的實現時,沒必要真建立這樣一種結構,我們還是使用之前的順序表,也還是使用之前的程式,只需要對其進行一點小小的改變:
#include #define max 5//表示順序表申請的空間大小
int enqueue(int *a,int front,int rear,int data)
a[rear%max]=data;
rear++;
return rear;
}int dequeue(int *a,int front,int rear)
printf("%d ",a[front]);
//front不再直接 +1,而是+1後同max進行比較,如果=max,則直接跳轉到 a[0]
front=(front+1)%max;
return front;
}int main()
程式執行結果:
1 2 3 4 5 6使用此方法需要注意的是,順序佇列在判斷陣列是否已滿時,出現下面情況: - 當隊列為空時,佇列的頭指標等於佇列的尾指標; - 當陣列滿員時,佇列的頭指標等於佇列的尾指標;
順序佇列的儲存狀態不同,但是判斷條件相同。為了對其進行區分,最簡單的解決辦法是:犧牲掉陣列中的乙個儲存空間,判斷陣列滿員的條件是:尾指標的下乙個位置和頭指標相遇,就說明陣列滿了,即程式中第 5 行所示。
不去追逐,永遠不會擁有。不往前走,永遠原地停留!
北徯的部落格www.xiangjunhong.com
C語言實現順序佇列
有關c語言實現佇列 1.佇列也是一種運算受限制的線性表,它只允許在表的一段 front 進行插入,在另一端 rear 進行刪除。2.佇列亦稱作先進先出的線性表,注意不能稱為後進後出。順序佇列結構描述 struct sq queue typedef struct sq queue sqqueue sq...
C語言實現,順序佇列,迴圈佇列,和棧!
佇列是一種特殊的 線性表,特殊之處在於它只允許在表的前端 front 進行刪除操作,而在表的後端 rear 進行插入操作,和棧一樣,佇列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。佇列的資料元素又稱為佇列元素。在佇列中插入乙個佇列元素稱為入隊,從佇列中刪除乙個佇列元...
佇列的順序儲存結構(迴圈佇列)(C語言實現)
1 include 2 include 3 4 define ok 1 5 define err 2 6 define true 1 7 define false 0 8 define maxsize 4 定義佇列的最大長度 910 typedef int status 定義函式返回的狀態,ok e...