佇列的鏈式儲存結構
總結佇列:是只允許在一端進行插入操作,而在另一端進行刪除操作。(可以是表頭,也可以是表尾)
我們可以看到,佇列其實也是線性表的一種,佇列的意思其實就和他的名字一樣,他的儲存特點就像乙個一堆資料排隊一樣,先排到隊裡面的資料就先出來(first in first out),簡稱fifo。允許插入的一段為表尾,允許刪除的一端稱為表頭。
operation //常用操作
initqueue
(*q)
//初始化操作,建立乙個空佇列q。
destroyqueue
(*q)
//若佇列q存在,則銷毀它。
clearqueue
(*q)
//將佇列q清空。
queueempty
(q)//若佇列q為空,返回true,否則返回false。
gethead
(q,*e)
//若佇列q存在且非空,用e返回佇列q的隊頭元素。
enqueue
(*q,e)
//若佇列q存在,插入新元素e到佇列q中並成為隊尾元素。
dequeue
(*q,
*e)//刪除佇列q中隊頭元素,並用e返回其值。
queuelength
(q)//返回佇列q的元素個數。
因為佇列也是線性表的一種,所以如果佇列要儲存 n 個元素,就要建立乙個長度為 n+1 的陣列。
我們的入佇列操作就是在隊尾新增乙個元素很明顯,其時間複雜度為o(1);但是出佇列就不同了,在這裡可以想到兩種方法。方法一:執行出佇列操作時,刪除隊頭元素,並且把後面的元素向前移動,他的時間複雜度為o(n),我們可以發現,他並不是乙個好方法,他的時間複雜度太高了,所以我們有了方法二:只刪除隊頭操作,不進行移動,誒~這時間複雜度就好看多了o(1)。
但是我們又遇到了乙個新的問題,那就是,我們的元素總要進進出出吧,當我們的隊尾位置是陣列的最後乙個位置時,就無法進行進佇列的操作了,但是,我們的隊頭不一定就是陣列的起始位置啊,可能排在老後面呢,這樣的話,就存在空間的浪費了。
解決這個問題的辦法其實很簡單,就是吧這個陣列從一條線,看成乙個圓,裡面的下標是迴圈的,假設有乙個大小為5的數列,那麼我們可以把它看成:0,1,2,3,4,0,1,2,3,4,0······這樣,就很完美的解決了空間浪費的問題。
還有乙個小問題,如果是迴圈佇列,要怎樣確定它存滿了呢?假設我們把隊頭取名為(front),隊尾的下乙個位置為(rear),則當 front == rear 時,表示隊列為空。這裡又兩種方法:
①建立乙個 flag 變數,有元素時為1,沒有元素時為0,當 front == rear 時,如果 flag 為1,則佇列滿;否則佇列空。
②在隊尾留乙個空位置,意思是存滿時其實只存了陣列大小減1個元素,這時,存滿的標識即為 (rear+1)%arraylength == front (這裡的arraylength指數組的大小)
我們著重介紹方法二,佇列的結構為:
#define ok 1
#define error 0
#define ture 1
#define false 0
typedef
int status;
/*status是函式的型別,其值是函式結果狀態**,如ok等*/
typedef
int qelemtype;
/* 這是迴圈佇列的順序儲存結構 */
typedef
struct
sqqueue;
status initqueue
(sqqueue *q)
int
queuelength
(sqqueue q)
status enqueue
(sqqueue *q,qelemtype e)
status dequeue
(sqqueue *q,qelemtype *e)
他們的時間複雜度都為o(1),同樣順序儲存結構的缺點就是他們的長度在一開始就已經確定了,如果資料過多,也無法在後期增加長度了。所以,它的好兄弟鏈式儲存結構,他來了。
佇列的鏈式儲存結構,其實就是線性表的單鏈表,只不過它只能尾進頭出,我們把它簡稱為鏈佇列。在鏈佇列中, front 指向佇列的頭節點, rear 指向終端結點,當隊列為空時, front 和 rear 都指向頭節點。(注意頭節點與頭指標之間的異同)
#define ok 1
#define error 0
#define ture 1
#define false 0
typedef
int status;
typedef
int qelemtype;
typedef
struct qnodeqnode,
*queueptr;
typedef
struct
linkqueue;
status enqueue
(linkqueue *q,qelemtype e)
status dequeue
(linkqueue *q,qelemtype *e)
可以看出,它們的時間複雜度都為o(1)。
首先,佇列的性質我們要清楚,就是一端進,另一端出。
其次,對比它的兩種儲存結構。我們可以發現,這兩種儲存結構的基本操作的時間複雜度都為o(1),他們的主要區別就是儲存空間的不同,對於順序儲存結構,他在一開始就固定了儲存空間大小的,所以它的最多存放的資料是固定多的,但是鏈式儲存結構則在理論上可以儲存無限個資料,但因為每個結點需要存放下乙個結點的位址,所以儲存相同資料使用的大小要比順序儲存空間多。我們應視情況而考慮用哪一種儲存結構。
資料結構之佇列 c語言版
佇列 queue 在邏輯上是一種線性儲存結構。它有以下幾個特點 1 佇列中資料是按照 先進先出 fifo,first in first out 方式進出佇列的。2 佇列只允許在 隊首 進行刪除操作,而在 隊尾 進行插入操作。佇列通常包括的兩種操作 入佇列 和 出佇列。底層可以由陣列 順序表 鍊錶實現...
資料結構(C語言版) 佇列
1 佇列 在表的一端插入,表的另一端刪除,允許插入的一端為隊尾,允許刪除的一端為隊頭。先進先出fifo。2 佇列的基本操作 initqueue q 構造空佇列 destroyqueue q 銷毀佇列 clearqueue q 清空佇列 queueempty q 判斷佇列是否為空 queuelengt...
資料結構(C語言版)
用棧實現數字的進製轉換 10轉8 棧 限定只能在表尾進行插入或者刪除操作的線性表 特點 先進後出 儲存表示方法 順序棧和鏈棧 本文用的順序棧 實現 readonly name code class c include include define stack init size 100 儲存空間初始...