佇列(queue)是一種採用先進先出(fifo)策略的抽象資料結構,它的想法來自於生活中排隊的策略。顧客在付款結賬的時候,按照到來的先後順序排隊結賬,先來的顧客先結賬,後來的顧客後結賬。
同棧的實現一樣,佇列的實現也有陣列實現和鍊錶實現兩種方式。
先來看看陣列實現的方法。棧使用top變數記錄棧頂的位置,而佇列則使用front和rear分別佇列第乙個元素和最後乙個元素的位置。
#define size 20
typedef
struct
queue
queue;
入隊、出隊操作很簡單。入隊時,通過rear的位置判斷佇列是否已滿。如果沒有滿,則將rear後移一位,將新元素放置在rear所在位置。出隊時,也可以通過rear的位置判斷佇列是否為空。如果不空,則只需將front後移一位即可。 獲取隊頭元素,判斷佇列不空,則只需返回front指向位置的元素即可。
哇塞!好簡單啊!這樣就完成了佇列的實現啊!太天真了。。。想一下,通過出隊操作將資料彈出佇列後,front之前的空間還能夠再次得到嗎?不能。所以使用普通陣列實現佇列,就再也不能使用front之前的空間了,這會導致大量空間丟失。
為了解決這個問題,將普通陣列換成迴圈陣列。在迴圈陣列中,末尾元素的下乙個元素不是陣列外,而是陣列的頭元素。這樣就能夠再次使用front之前的儲存空間了。
哇塞!有解決了這個問題。可以開始碼**了!且慢,在實現修改入隊和出隊操作之前,再深思一步,這時是否還能簡單通過判斷rear的位置來判斷佇列空或滿呢?當然不可以。那是否可以考慮front和rear之間的位置關係呢?考慮如下兩種邊界情況:
在這兩種情況下,rear都在front前乙個位置,無法判斷此時佇列滿還是空。為了解決這個問題,通常採用的最簡單的方法就是,使用乙個counter記錄佇列中元素個數。修改佇列定義為下:
#define size 20
typedef
struct
queue
queue;
init(queue *q)
bool isfull(queue *q)
void enqueue(queue *q, int val)
bool isempty(queue *q)
void dequeue(queue *q)
//get the front element from queue
int front(queue *q)
另外一種方法是,在陣列中空出乙個位置,用以標記佇列是否已滿。
*q)有時候,rear表示隊尾元素的下乙個位置,即表示即將插入元素的位置。
此時,判斷佇列的操作應該修改如下:
#define size 20
typedef
struct
queue
queue;
init(queue *q)
bool isfull(queue *q)
void enqueue(queue *q, int val)
bool isempty(queue *q)
void dequeue(queue *q)
int front(queue *q)
佇列的陣列實現比較麻煩,需要考慮各種邊界情況,所以通常使用鍊錶形式來實現佇列。
使用單向鍊錶來實現鏈式佇列,鏈式佇列中儲存front和rear即可。
typedef
struct node
node;
typedef
struct
queue
;
為了方便實現,鏈式佇列中的front表示鍊錶的頭節點,而front的next才表示隊頭。鏈式佇列的入隊和出隊操作如下圖所示。從圖中可以看出鏈式佇列的實現採用尾進頭出的策略。
在鏈式佇列中,不需要考慮佇列是否已滿,只要記憶體足夠就可以一直分配空間。而當front和rear都指向頭節點的時候,則表示此時隊列為空。
bool isempty(queue
*q)
入隊時移動rear指向最後乙個元素即可。
node* createnode(int val)
}void enqueue(queue
*q, int val)
}
出隊時,不需要移動front指標,只需將其next指標指向下乙個next元素即可。q->front->next = q->front->next->next;
但是需要考慮一種特殊情況,即當佇列中只剩下乙個元素時,還需要使rear指標重新指向頭節點。
int front(queue
*q)void dequeue(queue
*q)}
資料結構 佇列 queue
佇列 就是生活中的排隊,因此排隊是先到先得,也是先離開隊伍,因此佇列也是採用的先進先出的概念 fifo,慢慢想想作業系統裡面是不是也用到fifo,自己去查吧 到底有沒有 如何能夠準確的定位是先進先出呢,因此採用的就是頭指標front和尾指標rear,通常這兩個指標是封裝成乙個鏈隊 注意front與r...
資料結構 佇列queue
佇列 佇列是一種特殊的線性表,特殊之處在於它只允許在表的前端 front 進行刪除操作,而在表的後端 rear 進行插入操作,和棧一樣,佇列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。佇列是有序集合,新新增的一端為隊尾,另一端為隊頭,當乙個元素從隊尾進入佇列時,一直...
資料結構之佇列(Queue)
佇列,顧名思義,也就是一條隊伍,進入隊伍的時候,只能從隊尾排隊,離開隊伍的時候,只能從隊首離開。佇列也有陣列實現和鏈式實現。用一般陣列實現佇列的時候,入隊,則在隊尾插入乙個元素,出隊,則將隊首的元素出隊。那麼,由於陣列的長度是固定的,入隊只能從隊尾入隊,因此經常性的出隊會使得隊首越來越靠近隊尾,隊首...