標籤:順序隊列 隊列的順序儲存
和棧相反,隊列是一種先進先出的的線性表。它只允許在表的一端進行插入,而在另一端刪除元素。這和我們日常生活中的隊列是一致的,最早進入隊列的元素最早離開。在隊列中,允許插入的一端叫做隊尾,允許刪除的一端則稀爛為隊頭。
順序隊列,即隊列的順序儲存結構。由於隊列的隊頭和隊尾的位置均發生變化,因此在隊列順序儲存結構中,除了用一組地址連續的儲存單元依次存放從隊頭到隊尾的元素之外,還需要附設兩個指標front和rear指向隊頭和隊尾元素。
為了操作方便,在此約定:在非空隊列中,隊頭指標front始終指向隊頭元素,而隊尾rear始終指向隊尾元素下一個位置。
順序隊列的類型描述:
//順序隊列的類型描述#define MAXSIZE 100typedef int ElemType;typedef struct{ElemType *data;int front,rear;}SqQueue;
基本操作:
1. 初始化順序隊列Init_SqQueue(SqQueue* Q):
//初始化順序隊列void Init_SqQueue(SqQueue* Q){ Q->data = (SqQueue*)malloc(sizeof(SqQueue) * MAXSIZE);Q->front = Q->rear = 0;}
2. 銷毀順序隊列Destroy_SqQueue(SqQueue* Q)
//銷毀順序隊列void Destroy_SqQueue(SqQueue* Q){if(Q->data){free(Q->data);Q->front = Q->rear = 0;}}
3. 清空順序隊列Clear_SqQueue(SqQueue* Q)
//清空順序隊列void Clear_SqQueue(SqQueue* Q){Q->front = Q->rear = 0;}
4. 判斷順序隊列是否為空白IsEmpty_SqQueue(SqQueue* Q)
//判斷順序隊列是否為空白int IsEmpty_SqQueue(SqQueue* Q){if(Q->front == Q->rear)return 1;else{return 0;}}
5. 判斷順序隊列是否已滿iSFull_SqQueue(SqQueue* Q)
//判斷順序隊列是否已滿int iSFull_SqQueue(SqQueue* Q){if(Q->rear == MAXSIZE)return 1;elsereturn 0;}
因為沒有設定額外的指標,所以這裡判斷順序隊列是否已滿,實際上是假溢出,並不是真的順序隊列滿,原因:
隨著入隊,出隊的進行,整個隊列會整體向後移動,這樣就出現隊尾指標已經移動到了最後,再有元素入隊就會出現隊滿,即溢出,而事實上此時隊中並未真正的滿員,這種現象即稱為“假溢出”。
6. 求得順序隊列的長度GetLength_SqQueue(SqQueue* Q)
//求得順序隊列的長度int GetLength_SqQueue(SqQueue* Q){return Q->rear - Q->front;}
7. 取得順序隊列的的隊頭GetHead_SqQueue(SqQueue* Q,ElemType *x)
//取得順序隊列的的隊頭void GetHead_SqQueue(SqQueue* Q,ElemType *x){if(IsEmpty_SqQueue(Q)){printf("順序隊列空!\n");exit(0);}else{*x = Q->data[Q->front];}}
8. 取得順序隊列的的隊尾GetRear_SqQueue(SqQueue* Q,ElemType *x)
//取得順序隊列的的隊尾void GetRear_SqQueue(SqQueue* Q,ElemType *x){if(IsEmpty_SqQueue(Q)){printf("順序隊列空!\n");exit(0);}else{*x = Q->data[Q->rear - 1];}}
9. 入順序隊列En_SqQueue(SqQueue* Q,ElemType x)
//入順序隊列void En_SqQueue(SqQueue* Q,ElemType x){Q->data[Q->rear] = x;Q->rear++;}
10. 出順序隊列De_SqQueue(SqQueue* Q,ElemType *x)
//出順序隊列void De_SqQueue(SqQueue* Q,ElemType *x){if(IsEmpty_SqQueue(Q)){printf("順序隊列空!\n");exit(0);}else{*x = Q->data[Q->front];Q->front++;}}
11. 列印順序隊列Print_SqQueue(SqQueue* Q)
//列印順序隊列void Print_SqQueue(SqQueue* Q){int i = Q->front;if(IsEmpty_SqQueue(Q)){printf("順序隊列空!\n");exit(0);}else{while(i < Q->rear)printf("%d\t",Q->data[i++]);printf("\n");}}
說明:
以上這種順序隊列會出現“假溢出”,隨著入隊,出隊的進行,整個隊列會整體向後移動,這樣就出現隊尾指標已經移動到了最後,再有元素入隊就會出現隊滿,即溢出,而事實上此時隊中並未真正的滿員。
為了能充分的利用空間,解決順序隊列的“假溢出”問題,可以採用兩種方法:一種是將資料向前移動,讓空的儲存單元留在隊尾;另一種是將順序隊列構造成一個環狀的空間,即將隊列的資料區data[0....MAXSIZE-1]看成頭尾相接的迴圈結構,使得data[0]接在data[MAXSIZE-1]之後,這就是迴圈隊列。
資料結構(C實現)------- 順序隊列(非迴圈隊列)