佇列是只允許在一端進行插入操作,而在另一端進行刪除操作的線性表。
佇列是一種先進先出的線性表,簡稱fifo。允許插入的一端稱為隊尾,允許刪除的一端稱為隊頭。
同樣是線性表,佇列也有類似線性表的各種操作,不同的就是插入資料只能在隊尾進行,刪除資料只能在隊頭進行。
adt 佇列(queue)
data
同線性表。元素具有相同型別,相鄰元素具有前驅和後繼關係
operattion
initqueue(*q) :初始化操作,建立乙個空佇列q
destroyqueue(*q): 若佇列q存在,則銷毀它
clearqueue(*q) :清空q
queueempty(q):若佇列q為空,返回true,否則返回false
gethead(q,*e):若佇列q存在且非空,用e返回佇列q的隊頭元素。
endqueue(*q,e):若佇列q存在,輸入新元素e到佇列q中並成為隊尾元素
dequeue(*q,*e):刪除佇列q中隊頭元素,並用e返回其值
queuelength(q):返回佇列q的元素個數
endadt
線性表有順序儲存和鏈式儲存,棧是線性表,所以有兩種儲存方式。同樣,佇列作為一種特殊的線性表,也同樣存在這兩種儲存方式。
佇列順序儲存的不足
假設乙個佇列有n個元素,則順序儲存的佇列需要建立乙個大於n的陣列,並把佇列的所有元素儲存在陣列的前n個單元,陣列下標為0的一即是隊頭。所謂的入佇列操作,其實就是在隊尾追加乙個元素,不需要移動任何元素,因此時間複雜度為o(1)
與棧不同的是,佇列元素的出列是在隊頭,即下標為0的位置,那麼就意味著佇列中的所有元素都得向前移動,以保證佇列的隊頭,也就是下標為0的位置不為空,此時時間複雜度為o(n)
如果隊頭出隊,而不移動元素,那麼出隊的效能就會大大增加。也就是說,隊頭不需要一定在下標為0的位置。為了避免當只有乙個元素時,隊頭和附屬重合,front指標指向隊頭元素,rear指標指向隊尾元素的下乙個位置,當front==rear時此隊列為空。
假設是長主為5的陣列,初始狀態,空佇列。front與rear指標均指向下標為0的位置。然後a1/a2/a3/a4,入隊front指標依然指向下標為0位置,而rear指標指向下標為4的位置。
出隊a1、a2,則front指標指向下標為2的位置,rear不變,再入隊a5,此時front指標不變,rear指標移動到陣列之外 ,這種現象是假溢位。
迴圈佇列定義
所以解決假溢位的辦法就是後面滿了,就再從頭開始,也就是頭尾相接的迴圈。我們把佇列的頭尾相接的順序儲存結構稱為迴圈佇列。
接著上面a6入隊,將它放置於下標為0處,rear指標指向下標為1處,若再入隊a7,則rear指標就與front指標重合,同時指向下標為2的位置。
此時問題又出來了,我們剛才說,空佇列時,front等於rear,現在當佇列滿時,也是front等於rear那麼如何判斷此時的佇列空間是空還是滿呢?
辦法是設定乙個標誌變數flag,當front==rear,且flag=0佇列空,當front==rear且flag=1時隊滿
辦法二是當佇列空時,條件就是front==rear,當佇列滿時,我們修改其條件,保留乙個元素空間。也就是說佇列滿時,陣列中還有乙個空閒的單元,
我們重點來討論第二種方法,由於rear可能比front大,也可能比front小,所以儘管它們只相差乙個位置時就是滿情況,但也可能是相差整整一圈。所以若佇列的最大尺寸為queuesize,那麼佇列滿的條件是(rear+1)%queuesize==front
通用的計算佇列長度的公式:(rear-front+queuesize)%queuesize
迴圈佇列的順序儲存結構**:
typedef
int qelemtype
typedef
struct
sqqueue;
//初始化**
status initqueue(sqqueue *q)
//求佇列長度
int queuelength(qqqueue q)
//入隊操作
status enqueue(sqqueue *q,qelemtype e)
//出隊操作
status dequeue(sqqueue *q,qelemtype *e)
佇列的鏈式儲存結構,其實就是線性表的單鏈表,只不過它只能尾進頭出而已,我們把它簡稱為鏈佇列。
//結點結構
typedef
struct qnode
qnode,*queueptr;
//佇列的鍊錶結構
typedef
struct
linkqueue;
佇列的鏈式儲存結構—-入隊操作
入隊操作時,其實就是在鍊錶尾部插入結點。
status enqueue (linkqueue *q,qelemtype e)
佇列的鏈式儲存結構—-出隊操作
出隊操作時,就是頭結點的後繼結點出隊,將頭結點的後繼改為它後面的結點,若煉表除頭結點外只剩乙個元素時,則需將rear指向頭結點
/*若佇列不空,刪除q的隊頭元素,用e返回其值,並返回ok,否則返回error*/
status dequeue (linkqueue *q,qelemtype *e)
學習筆記 資料結構(三) 佇列和棧
用python實現棧 棧的儲存順序是先入後出。class stack object def init self self.stack def push self,value 進棧 def pop self 出棧 if self.stack self.stack.pop else raise look...
資料結構學習筆記(5) 佇列
二 佇列的鏈式儲存實現 佇列是具有一定操作約束的線性表,只能在一端插入,在另一端刪除 佇列是先進先出 fifo 的線性結構 型別名稱 佇列 queue 資料物件集 乙個有0個或者多個元素的有窮線性表 操作集 長度為maxsize的佇列q in queue,佇列元素item in elementtyp...
資料結構學習筆記 3 佇列
型別名 佇列 queue 資料物件集 乙個有0個或多個元素的有窮線性表 操作集 長度為maxsize的堆疊q queue,佇列元素item elementtype 1.生成長度為maxsize的空佇列 queue creatqueue int maxsize 2.判斷佇列q是否已滿 bool isf...