資料結構中佇列的實現(基於順序表迴圈佇列)
阿新 • • 發佈:2019-02-03
在學習資料結構中,佇列也是一個重要的資料結構,我們今天來用基於順序表的佇列(Queue),
在基於順序表佇列如果是不迴圈的順序表,則在出佇列時,時間複雜度是O(n),所以我們用迴圈佇列來
實現,怎麼解釋基於迴圈順序表的佇列呢?
我們上圖:
上圖是在不迴圈順序表中出隊。這樣不難看出時間複雜度不是很好。
所以我們來順序迴圈佇列,把順序表讓它迴圈利用。
看圖
上圖就是順序表迴圈佇列,a就是隊首,d就是隊尾,這樣可以避免出隊後移位,所以就時間複雜度更小。
那麼咱們來看程式碼:
先是宣告:
#pragma once #include<stdio.h> #define MAXREPOSITORY 10 #define TEAM_HEAD printf("\n===========%s==========\n",__FUNCTION__) typedef char QueueType; typedef struct SeqQueue{ size_t count; size_t size; QueueType data[MAXREPOSITORY]; }SeqQueue; // 初始化。 void InitSeqQueue(SeqQueue *seq); // 入隊。 void PushQueue(SeqQueue *seq,QueueType value); // 出隊。 void PopQueue(SeqQueue *seq); // 取隊首元素。 QueueType FindHead(SeqQueue *seq); // 取隊尾元素。 QueueType FindBottom(SeqQueue *seq); // 銷燬。 void DestoryQueue(SeqQueue *seq);
看定義:
#include"SeqQueue.h" // 初始化。 void InitSeqQueue(SeqQueue *seq) { if (seq == NULL) { return; } seq->size = 0; seq->count = 0; } // 入隊。 void PushQueue(SeqQueue *seq,QueueType value) { if (seq == NULL) { return; } if (seq->count == MAXREPOSITORY) { // 佇列滿。 return; } // 當迴圈順序隊迴圈完但隊未滿時,進行迴圈。 if (seq->size > MAXREPOSITORY) { seq->size = 0; } seq->data[seq->size] = value; ++seq->size; ++seq->count; } // 出隊。 void PopQueue(SeqQueue *seq) { if (seq == NULL) { return; } if (seq->count == 0) { // 空佇列。 return; } --seq->count; } // 取隊尾元素。 QueueType FindButtom(SeqQueue *seq) { if (seq == NULL) { printf("輸入錯誤\n"); return 0; } if (seq->count == 0) { printf("隊為空\n"); return 0; } return seq->data[seq->size-1]; } // 取隊首元素。 QueueType FindHead(SeqQueue *seq) { if (seq == NULL) { printf("輸入錯誤\n"); return 0; } if (seq->count == 0) { printf("隊為空\n"); return 0; } if (seq->size >= seq->count) { return seq->data[seq->size - seq->count]; } else { size_t tmp = seq->count-seq->size; size_t size = MAXREPOSITORY; return seq->data[size-tmp]; } } // 銷燬。 void DestoryQueue(SeqQueue *seq) { if (seq == NULL) { return; } seq->size = 0; seq->count = 0; } //////////////// //以下為測試程式碼 //////////////// void PrintSeqQueue(SeqQueue *seq) { if (seq == NULL) { return; } printf("[隊尾]->"); size_t count = 0; size_t size = seq->size; if (size != 0) { while (seq->count > count) { printf("[%c]->",seq->data[size-count-1]); count++; } // for (; count < seq->count; ++count) // { // printf("[%c]<-",seq->data[count]); // } } else { while (seq->count > count) { // 當迴圈到最大size但是隊未滿。 if (size - count - 1 == 0) { printf("[%c]->",seq->data[size-count-1]); size = MAXREPOSITORY; count++; } else { printf("[%c]->",seq->data[size-count-1]); count++; } } // for(; count < seq->count; ++count) // { // if (size-count == 0) // { // size = MAXREPOSITORY; // } // printf("[%c]<-",seq->data[size-count]); // } } printf("[隊頭]\n"); } // 順序隊的初始化。 void TestInitSeqQueue() { TEAM_HEAD; SeqQueue seq; InitSeqQueue(&seq); } void TestPushQueue() { TEAM_HEAD; SeqQueue seq; InitSeqQueue(&seq); PushQueue(&seq, 'a'); PushQueue(&seq, 'b'); PushQueue(&seq, 'c'); PushQueue(&seq, 'd'); PrintSeqQueue(&seq); } void TestPopQueue() { TEAM_HEAD; SeqQueue seq; InitSeqQueue(&seq); PushQueue(&seq, 'a'); PushQueue(&seq, 'b'); PushQueue(&seq, 'c'); PushQueue(&seq, 'd'); PushQueue(&seq, 'e'); PrintSeqQueue(&seq); PopQueue(&seq); PopQueue(&seq); PopQueue(&seq); PopQueue(&seq); PrintSeqQueue(&seq); PushQueue(&seq, 'f'); PushQueue(&seq, 'g'); PushQueue(&seq, 'h'); PushQueue(&seq, 'i'); PushQueue(&seq, 'j'); PushQueue(&seq, 'k'); PrintSeqQueue(&seq); } void TestFindButtom() { TEAM_HEAD; SeqQueue seq; InitSeqQueue(&seq); PushQueue(&seq, 'a'); PushQueue(&seq, 'b'); PushQueue(&seq, 'c'); PushQueue(&seq, 'd'); PushQueue(&seq, 'e'); PrintSeqQueue(&seq); QueueType ret = FindButtom(&seq); printf("except e actual %c",ret); } void TestFindHead() { TEAM_HEAD; SeqQueue seq; InitSeqQueue(&seq); PushQueue(&seq, 'a'); PushQueue(&seq, 'b'); PushQueue(&seq, 'c'); PushQueue(&seq, 'd'); PushQueue(&seq, 'e'); PrintSeqQueue(&seq); PopQueue(&seq); PopQueue(&seq); PopQueue(&seq); PopQueue(&seq); PrintSeqQueue(&seq); PushQueue(&seq, 'f'); PushQueue(&seq, 'g'); PushQueue(&seq, 'h'); PushQueue(&seq, 'i'); PushQueue(&seq, 'j'); PushQueue(&seq, 'k'); PrintSeqQueue(&seq); QueueType ret = FindHead(&seq); printf("except e actual %c",ret); } void TestDestoryQueue() { TEAM_HEAD; SeqQueue seq; InitSeqQueue(&seq); PushQueue(&seq, 'a'); PushQueue(&seq, 'b'); PushQueue(&seq, 'c'); PushQueue(&seq, 'd'); PushQueue(&seq, 'e'); PrintSeqQueue(&seq); DestoryQueue(&seq); PrintSeqQueue(&seq); } int main() { TestInitSeqQueue(); TestPushQueue(); TestPopQueue(); TestFindButtom(); TestFindHead(); TestDestoryQueue(); return 0; }
順序表迴圈佇列中,最需要注意的就是在順序表到達最大位置時,
需要將size置為0,所以我們添加了一個變數count來計數隊中元素的個數,
這樣就可以判斷佇列是否滿,還有在列印佇列中也需要注意列印的順序,是從前往後列印還是相反
要明確。我呢,是採用從隊尾列印,也就是先列印呢size值大的。
如有不足請多多指教。