嚴蔚敏版資料結構——佇列(順序表表示)
阿新 • • 發佈:2018-12-11
佇列有兩種表示方式,我們先看順序表示:
程式碼中的rear(尾指標)與front(頭指標)都是int 型的,它的作用就是做陣列下標,我們習慣稱它為指標,這裡應該注意它不是指標型別。頭指標始終指向佇列頭元素,尾指標始終指向隊尾元素的下一個位置。
由於增加元素rear加一,刪除元素front也加一,沒錯都是加一。就像一排10個座位,一開始只有前面三個座位有人,但我們的規則是:只能前面的同學離開,後來的同學只能坐後面。這樣的話過了一會兒會發現同學們都坐在後面,而前面的座位沒人坐,這就尷尬了——明明前面有位子卻不能坐,班長說已經滿了,再坐後面就沒座位了(溢位)。我們肯定會質疑這個規則有毛病,但是班長說把10個座位圍起來形成一個圓圈,第10號座位後面跟著第1號。哎!這個辦法不錯,既沒有違背規則,又沒有浪費位子。這就可以用“模”運算解決迴圈問題,即滿了10我們就讓他變為0,其他是多少就是多少。當增加一個元素時rear=(rear+1)%10, (注意陣列下標0開始,扭轉思維)。
下面我們來思考一個問題:
【1】 當一個人都沒有的時候,front==rear;當全部坐滿的時候 rear==front;由此可見,迴圈佇列不能以頭尾指標是否相同來判別佇列是否為空。這裡我們採用空出一個位置的方法來標記是否隊滿:
記住下面兩點(很重要):
隊空的條件:front==rear;
隊滿的條件:(rear+1)% MAXSIZE==front;
接下來還是看程式碼實現來的爽快:
#include<stdio.h> #include<malloc.h> #define OK 1 #define ERROR 0 #define MAXSIZE 20 typedef struct { int data; }MyType; typedef struct { MyType *base; //注意這兩個標記不是指標型別,屬於陣列下標。但我們習慣叫它指標; int front; int rear; }SqQueue; //---------------初始化佇列---------------- int InitQueue(SqQueue & Q) { //構造一個空佇列 Q.base=new MyType[MAXSIZE]; if(Q.base==NULL) return ERROR; Q.front=Q.rear=0; return OK; } //--------------求佇列的長度---------------- int QueueLength(SqQueue Q) { //因為是迴圈佇列,所以rear可以比front小,一減就是負數,其絕對值也就是空位置的大小 //MAXSIZE減去空位置就是長度 return (MAXSIZE+Q.rear-Q.front)%MAXSIZE; } //--------------入隊操作--------------- int EnQueue(SqQueue &Q,MyType e) { //先判斷滿了沒 if((Q.rear+1)%MAXSIZE==Q.front) return ERROR; Q.base[Q.rear].data=e.data; Q.rear=(Q.rear+1)%MAXSIZE; return OK; } //-------------出隊操作----------------- int DeQueue(SqQueue &Q,MyType &e) { //先判斷是不是空佇列 if(Q.front==Q.rear) return ERROR; e.data=Q.base[Q.front].data; Q.front=(Q.front+1)%MAXSIZE; return OK; } //--------------取迴圈佇列對頭元素---------- MyType GetHead(SqQueue Q) { //不是空就這樣幹 if(Q.front!=Q.rear) return Q.base[Q.front]; } //-------------打印出來看看------------- void Print(SqQueue Q) { int i; for(i=Q.front;i<Q.rear;i++) { printf("第%d個位置是:%d\n",i+1,Q.base[i].data); } } //--------------輸入資料--------------- void Scanf(SqQueue &Q,int n) { int i,data; MyType datatype; for(i=0;i<n;i++) { printf("請輸入第%d個數:",i+1); scanf("%d",&datatype.data); EnQueue(Q,datatype); } printf("\n\n"); } int main() { MyType mydata; SqQueue Q; InitQueue(Q); Scanf(Q,4); Print(Q); printf("\n隊頭的元素是:%d ",GetHead(Q)); DeQueue(Q,mydata); printf("\n出隊的元素是:%d",mydata.data); printf("\n出隊後的佇列是這樣的:\n"); Print(Q); printf("重新入隊後的佇列是:\n"); EnQueue(Q,mydata); Print(Q); return 0; }
執行結果如下: