基本操作
插入新元素,使用PASCAL語言:
過程DEL2(Q,Y,F)從循環佇列q中取出隊首元素
條件處理
循環佇列中,由於入隊時尾指針向前追趕頭指針;出隊時頭指針向前追趕尾指針,造成隊空和隊滿時頭尾指針均相等。因此,無法通過條件front==rear來判別佇列是"空"還是"滿"。
解決這個問題的方法至少有兩種:
① 另設一布爾變數以區別佇列的空和滿;
②另一種方式就是數據結構常用的: 隊滿時:(rear+1)%n==front,n為佇列長度(所用數組大小),由於rear,front均為所用空間的指針,循環只是邏輯上的循環,所以需要求余運算。如圖情況,隊已滿,但是rear(5)+1=6!=front(0),對空間長度求余,作用就在此6%6=0=front(0)。
類型定義採用環狀模型來實現佇列,各數據成員的意義如下:
front指定隊首位置,刪除一個元素就將front順時針移動一位;
rear指向元素要插入的位置,插入一個元素就將rear順時針移動一位;
count存放佇列中元素的個數,當count等於MaxQSize時,不可再向佇列中插入元素。
隊空:count=0
隊滿:count=MaxQSize
#define QueueSize 100//應根據具體情況定義該值
typedef char DataType;//DataType的類型依賴於具體的套用
typedef struct{
int front;//頭指針,隊非空時指向隊頭元素
int rear;//尾指針,隊非空時指向隊尾元素的下一位置
int count;//計數器,記錄隊中元素總數DataTypedata[QueueSize];
}CirQueue;
基本運算
用第三種方法,循環佇列的六種基本運算:
① 置隊空
voidInitQueue(CirQueue*Q){ Q->front=Q->rear=0;Q->count=0; }//計數器置0
② 判隊空
intQueueEmpty(CirQueue*Q){ returnQ->count==0; }//佇列無元素為空
③ 判隊滿
intQueueFull(CirQueue*Q){ returnQ->count==QueueSize;}//隊中元素個數等於QueueSize時隊滿
④ 入隊
voidEnQueue(CirQueue*Q,DataTypex){
if(QueueFull(Q))Error("Queueoverflow"); //隊滿上溢
Q->count++; //佇列元素個數加1
Q->data[Q->rear]=x; //新元素插入隊尾
Q->rear=(Q->rear+1)%QueueSize; //循環意義下將尾指針加1
}
⑤ 出隊
DataTypeDeQueue(CirQueue*Q){
DataType temp;
if(QueueEmpty(Q))Error("Queueunderflow"); //隊空下溢
temp=Q->data[Q->front];
Q->count--; //佇列元素個數減1
Q->front=(Q->front+1)%QueueSize; //循環意義下的頭指針加1returntemp;}
⑥取隊頭元素
DataTypeQueueFront(CirQueue*Q){
if(QueueEmpty(Q))Error("Queueisempty.");
returnQ->data[Q->front];
}
````````````````````````````````````````````````````````````````````````````````````
佇列的操作特點是“先進先出”。前者主要是頭指針、尾指針的使用,後者主要是理解循環佇列提出的原因及其特點。兩者都要掌握佇列空與滿的判定條件以及出佇列、入佇列操作的實現。