因爲循環隊列的特殊性,當隊首指針=隊尾指針的時候,既可能表示空也可能表示滿,因此須要另加一個判斷位。spa
我如今介紹的循環隊列判斷滿空的三種方法分別是:1.設標誌位法 2.預留一位法; 3.預存長度法(顧名思義,很簡單)指針
1.設標誌位法
code
思路:預設一個標誌,tag,初值=0,每當入隊成功,tag=1;每當出隊成功,tag=0;那麼,當front==rear && tag 則表示「在入隊操做以後front=rear」,顯然入隊形成的f=r的緣由就是滿了,故 front==rear && tag 表示隊列滿;同理,front==rear && !tag 表示隊列空。 隊列
例子:初始:front=-1,rear=-1,tag=0,下面對隊列queue[3]執行:入1,出2,出3,入4,入5,入6,入7,出8,入9,入10 的動做。it
(1)入1:此時f=r=-1,tag=0 說明爲空,能夠入隊,存入queue[rear++],入隊以後,tag=1, rear=rear+1%3;io
(2)出2:此時f=-1,r=0,能夠出隊,出隊內容是queue[front++],出隊以後,tag=0,front=front+1%3;class
(3)出3:此時f=r=0,tag=0 說明爲空,不能再出隊了,過;變量
(4)入4:此時f=r=0,tag=0 爲空,能夠入隊,存入queue[rear++],入隊以後,tag=1,rear=rear+1%3;循環
(5)入5:此時f=0,r=1,tag=0 ,能夠入隊,存入queue[rear++],入隊以後,tag=1,rear=rear+1%3;queue
(6)入6:此時f=0,r=2,tag=0 ,能夠入隊,存入queue[rear++],入隊以後,tag=1,rear=rear+1%3;
(7)入7:此時f=0=r,tag=1 ,說明隊列滿了,不可入隊,過;
(8)出8:此時f=0=r,tag=1 ,說明隊列滿,能夠出隊,出隊內容是queue[front++],出隊以後,tag=0,front=front+1%3;
(9)入9:此時f=1,r=0,tag=0 ,能夠入隊,存入queue[rear++],入隊以後,tag=1,rear=rear+1%3;
(10)入10:此時f=r=1,tag=1 ,說明隊列滿了,不可入隊,過;
代碼以下:
#include <stdio.h> #include <stdlib.h> #define MAXQUEUE 5 struct Student{ char name[20]; char id[20]; }; typedef struct Student student; student Queue[MAXQUEUE];// queue int front=-1; int rear=-1; int tag=0; void enqueue(student new); student* dequeue(); main(){ student mystu[10]={ {"LeechanX","1100300803"}, {"CongBaoE","1100300804"}, {"Hebe","1100300708"}, {"AiNi","1100300801"}, {"Wang","1100300812"}, {"PaoziBianwa","1100300831"}, {"Daijuhua","1100300829"}, {"Haomeng","1100300422"}, {"Gengbaoe","1100300621"}, {"Zhaoyan","1100300501"} }; int i=0; for(;i<2;i++) enqueue(mystu[i]); printf("Queue written over...\n"); student* stu; i=0; for(;i<1;i++){ stu=dequeue(); if(!stu) break; printf("Name:%s,ID:%s\n",stu->name,stu->id); printf("---\n"); } enqueue(mystu[3]); enqueue(mystu[4]); enqueue(mystu[5]); enqueue(mystu[6]); enqueue(mystu[7]); for(;;){ stu=dequeue(); if(!stu) break; printf("Name:%s,ID:%s\n",stu->name,stu->id); } } void enqueue(student new){ if(tag && front==rear) return; rear++; rear=rear%MAXQUEUE; Queue[rear]=new; tag=1; } student* dequeue(){ if(front==rear && !tag) return NULL; front++; front=front%MAXQUEUE; tag=0; return &(Queue[front]); }
2.預留一位法:
思路:讓front指向頭部以前的那一位,rear指向尾部,這樣一來,實際使用空間是SIZE-1。
當front=(rear+1)%SIZE or (front==-1 && rear=SIZE-2) 的時候,說明滿了(其實沒有滿,可是剩下的那個空間不可用)
當front==rear的時候,說明空。
這個方法相信全部的書裏都有。
例子:初始:front=-1,rear=-1,tag=0,下面對隊列queue[3]執行:入1,出2,出3,入4,入5,入6
(1)入1:此時f=r=-1說明爲空,能夠入隊,存入queue[rear++],入隊以後,tag=1, rear=rear+1%3;
(2)出2:此時f=-1,r=0,能夠出隊,出隊內容是queue[front++],出隊以後,tag=0,front=front+1%3;
(3)出3:此時f=r=0 說明爲空,不能再出隊了,過;
(4)入4:此時f=r=0 爲空,能夠入隊,存入queue[rear++],入隊以後,tag=1,rear=rear+1%3;
(5)入5:此時f=0,r=1,tag=0 ,能夠入隊,存入queue[rear++],入隊以後,tag=1,rear=rear+1%3;
(6)入6:此時f=0,r=2,(r+1)%SIZE=f,說明滿了,不能夠入隊,過; 存儲的實際空間是2。
#include <stdio.h> #include <stdlib.h> #define MAXQUEUE 5 struct Student{ char name[20]; char id[20]; }; typedef struct Student student; student Queue[MAXQUEUE]; int front=-1; // means start, using in dequeue(read) int rear=-1; // means end, using in enqueue(write) void enqueue(student new); student* dequeue(); main(){ student mystu[10]={ {"LeechanX","1100300803"}, {"CongBaoE","1100300804"}, {"Hebe","1100300708"}, {"AiNi","1100300801"}, {"Wang","1100300812"}, {"PaoziBianwa","1100300831"}, {"Daijuhua","1100300829"}, {"Haomeng","1100300422"}, {"Gengbaoe","1100300621"}, {"Zhaoyan","1100300501"} }; int i=0; for(;i<2;i++) enqueue(mystu[i]); printf("Queue written over...\n"); student* stu; i=0; for(;i<1;i++){ stu=dequeue(); if(!stu) break; printf("Name:%s,ID:%s\n",stu->name,stu->id); printf("---\n"); } enqueue(mystu[3]); enqueue(mystu[4]); enqueue(mystu[5]); enqueue(mystu[6]); enqueue(mystu[7]); for(;;){ stu=dequeue(); if(!stu) break; printf("Name:%s,ID:%s\n",stu->name,stu->id); printf("---\n"); } } void enqueue(student new){ if((rear+1)%MAXQUEUE==front || (front==-1 && rear==MAXQUEUE-2) ) return; rear++; rear=rear%MAXQUEUE; Queue[rear]=new; } student* dequeue(){ if(front==rear) return NULL; front++; front=front%MAXQUEUE; return &(Queue[front]); }
3.預存長度法:
思路:就是加一個變量存儲長度,入隊成功+1,出隊成功-1,=0空,=SIZE滿,太簡單,不說了。