9 棧和佇列(3)

2021-08-15 04:49:39 字數 3166 閱讀 5575

佇列(queue)是只允許在一端進行插入操作,而在另一端進行刪除操作的線性表。與棧相反,佇列是一種先進先出(first in first out, fifo)的線性表。與棧相同的是,佇列也是一種重要的線性結構,實現乙個佇列同樣需要順序表或鍊錶作為基礎。

我們的輸入緩衝區接受鍵盤的輸入就是按佇列的形式輸入和輸出的,不然的話就很容鬧出問題。例如有一天你突然心血來潮,用企鵝發了一句「you are my god」給你女朋友,表示她就是你的全部,但是輸入緩衝區在輸入god這個單詞的時候不用佇列這個結構而用棧的結構,就變成了「you are my dog」發出去了。。。。。。

佇列既可以用鍊錶實現,也可以用順序表實現。跟棧相反的是,棧一般我們用順序表來實現,而佇列我們常用鍊錶來實現,簡稱為鏈佇列。

typedef struct qnode  qnode, *queueprt;

typedef struct linkqueue;

將隊頭指標指向鏈佇列的頭結點,而隊尾指標指向終端結點。(注:頭結點不是必要的,但為了方便操作,我們加上了。)如下圖所示

空佇列時,front和rear都指向頭結點。

建立乙個佇列要完成兩個任務:一是在記憶體中建立乙個頭結點,二是將佇列的頭指標和尾指標都指向這個生成的頭結點,因為此時是空佇列。

typedef struct qnode  qnode, *queueprt;

typedef struct linkqueue;

入佇列的操作過程如下:

首先建立乙個結點,讓這個結點的位址為 p ;其次 e 1 的指標從指向 null(^),轉為指向 e2 ;最後將rear(尾指標)指向 e2,然後刪除 p 指標。

具體的**為

insertqueue(linkqueue *q, elemtype e)

上述的**中,q->rear指的是尾結點,q->rear->next = p;就是將 e1 的指標指向 p;q->rear = p;是將指標直接向後移,移動到最後一位。

出佇列操作是將佇列中的第乙個元素移出,隊頭指標不發生改變,改變頭結點的next指標即可。出佇列的操作過程如下:

如果原佇列只有乙個元素,那麼我們就應該處理一下隊尾指標。

具體的**為

deletequeue(linkqueue *q, elemtype *e)

由於鏈佇列建立在記憶體的動態區,因此當乙個佇列不再有用時應當把它及時銷毀掉,以免過多地占用記憶體空間。

destroyqueue(linkqueue *q)

}

在上述的過程中,元素一直從頂部取出元素。

為什麼小甲魚上節課說佇列的實現上我們更願意用鏈式儲存結構來儲存?我們先按照應有的思路來考慮下如何構造佇列的順序儲存結構,然後發掘都遇到了什麼麻煩。我們假設乙個佇列有n個元素,則順序儲存的佇列需建立乙個大於n的儲存單元,並把佇列的所有元素儲存在陣列的前n個單元,陣列下標為0的一端則是隊頭,如下圖所示

入佇列操作其實就是在隊尾追加乙個元素,不需要任何移動,時間複雜度為o(1)。出佇列則不同,因為我們已經架設下標為0的位置是佇列的隊頭,因此每次出佇列操作所有元素都要向前移動。

在現實中也是如此,一群人在排隊買火車票,前邊的人買好了離開,後面的人就要全部向前一步補上空位。可是我們研究資料結構和演算法的乙個根本目的就是要想方設法提高我們的程式的效率,按剛才的方式,出佇列的時間複雜度是o(n),效率大打折扣!如果我們不去限制隊頭一定要在下標為0的位置,那麼出佇列的操作就不需要移動全體元素。

但是這樣也會出現一些問題,例如按下邊的情形繼續入佇列,就會出現陣列越界的錯誤。

我們再想想,要解決假溢位的辦法就是如果後面滿了,就再從頭開始,也就是頭尾相接的迴圈。迴圈佇列它的容量是固定的,並且它的隊頭和隊尾指標都可以隨著元素入出佇列而發生改變,這樣迴圈佇列邏輯上就好像是乙個環形儲存空間。但要注意的是,在實際的記憶體當中,不可能有真正的環形儲存區,我們只是用順序表模擬出來的邏輯上的迴圈。

(rear+1) % queuesize

(front+1) % queuesize

首先定義乙個迴圈佇列

#define maxsize 100

typedef struct

初始化乙個迴圈佇列

initqueue(cyclequeue *q)

入佇列操作

insertqueue(cyclequeue *q, elemtype e)

出佇列操作

deletequeue(cyclequeue *q, elemtype *e)

棧和佇列 3順序佇列

adrian 由於順序佇列的底層使用的是陣列,因此需預先申請一塊足夠大的記憶體空間初始化順序佇列。除此之外,為了滿足順序佇列中資料從隊尾進,隊頭出且先進先出的要求,我們還需要定義兩個指標 top 和 rear 分別用於指向順序佇列中的隊頭元素和隊尾元素,如圖 1 所示 由於順序佇列初始狀態沒有儲存任...

第3章棧和佇列

在寫了2章部落格後我突然明白了許多,有些東西只是寫下來其實是沒有多大用,只不過是把東西從乙個地方搬到另乙個地方,而我其實的確是僅僅把課本上的內容抄了一遍而已,現在我覺得資料結構最重要的是演算法,因此如果想學好它首先應該把演算法看懂,其次把它理解著背過,畢竟最後還是用在操作上,所以我覺得第3章的重點在...

Chapter 3 棧和佇列

一 棧和佇列的基本概念 棧的基本概念 只能在一端進行插入或刪除的線性表。進行插入或刪除操作的一端稱為棧頂,另一端為棧底,棧底是固定不變的。棧的特點 filo 先進後出 棧的儲存結構 順序棧和鏈式棧 和線性表類似 棧的數學性質 當n個元素以某種順序如棧,並在入棧的過程中可以隨時出棧時,最終在所有元素經...