資料結構(三)--迴圈佇列
迴圈佇列的基本操作
剛把資料結構裡面的佇列學習了一下,主要是對迴圈佇列的基本操作進行了瞭解,主要是想明白,迴圈佇列的迴圈是咋實現的,就好了,然後把入隊和出隊,判斷是否是空,和判斷是否為滿的弄懂就搞清楚迴圈隊列了。
佇列
如圖所示,佇列是一種可以實現“先進先出”的儲存結構,哪一個節點元素先進來,它最先出去,然後如果想繼續加入節點,就在隊伍的最後面加入。
佇列分為鏈式佇列(用連結串列實現的)和靜態佇列(也就是迴圈佇列),在這篇部落格裡主要講的是迴圈佇列的基本操作。
迴圈佇列
迴圈佇列是靠陣列來實現的,就是如圖所示一樣的哈,想一條蛇,收尾相連,具體如何收尾相連,就是靠很簡單的取餘來實現的哈,對陣列的長度進行取餘,就可以迴圈了哈。//如果這裡不懂,看下面,繼續講解的哈。
引數font/rear
在好多書上講的是font是指向隊頭,rear是指向隊尾,但是這個操作起來不方便。下面分情況討論
1.佇列初始化
font和rear都為0//不懂的看上圖
2.佇列非空的時候(就是放值的時候)
font是佇列第一個元素
rear為佇列最後一個有效元素的下一個元素//這樣好操作
3.佇列為空
這個判斷起來很簡單
當font和rear相等的時候,但不一定為0
定義的結構體
typedef struct Queue{
int *pBase;
//這個是用來當定義的陣列的首地址的
int front;
//隊頭陣列的下標
int rear;
//佇列最後一個有效元素的下一個元素的下標
}QUEUE,*PQUEUE;
初始化
先建立好陣列空間
然後初始化font和rear都為0
下面這個是創了一個6個int型別元素的陣列,首地址為pQ->pBase
void init(PQUEUE pQ){
pQ->pBase = (int *)malloc(sizeof(int)*6);
pQ->front = 0;
pQ->rear = 0;
}
判斷迴圈佇列是否為滿
判斷迴圈佇列是否為滿有2種使用的方法
1.加個引數,記錄有效節點數,入隊就+1,出對就-1,判斷是否為滿,就看它是否和建立的陣列最大元素個數是否相同,但是不建議用這個方法,因為你還要重新開闢空間
2.浪費一個空間,陣列只能放(n-1)個元素,一開始font和rear相同,不斷入隊,rear就在圈上往上走,當它快走一圈的時候,也就是rear緊挨這個font
就是當(rear+1)%陣列的長度==front的時候
滿了
bool full_queue(PQUEUE pQ){
if((pQ->rear +1)%6 == pQ->front){
return true;
}else{
return false;
}
}
判斷是否為空
這個最簡單,就是他們font和rear相等的時候
bool out_queue(QUEUE*pQ,int *pVal){
if(empty_queue(pQ)){
return false;
}else{
*pVal = pQ->pBase[pQ->front];
pQ->front = pQ->front+1;
}
}
入隊
先判斷下佇列是否為滿
如果不滿的話,入隊
很簡單,把元素放在rear的位置就好了(之前定義說過,rear為佇列最後一個有效元素的下一個元素)
然後 rear=rear+1//這個不準確
又因為是迴圈佇列哈
真正的 rear = (rear+1)%陣列的長度
bool en_queue(PQUEUE pQ,int val){
if(full_queue(pQ)){
return false;
}else{
pQ->pBase[pQ->rear] = val;
pQ->rear = (pQ->rear+1) % 6;
returnt
ue;
}
}
出隊
先判斷佇列是否為空
如果是空的話就不出隊了
出隊的話也很簡單
就是把font=font+1//這個不準確
因為是迴圈的哈,所以font = (font+1)%陣列長度,,在這個函式裡,我還把出隊的元素記錄了下來
bool out_queue(QUEUE*pQ,int *pVal){
if(empty_queue(pQ)){
return false;
}else{
*pVal = pQ->pBase[pQ->front];
pQ->front = pQ->front+`
;
}
}
總的程式碼
這個迴圈佇列只是我定義為int型別的陣列,裡面有6個元素,這個可以自己修改,在初始化那塊改的
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
/*佇列的基本運用
所有和時間的操作都和佇列有關
*/
typedef struct Queue{
int *pBase;
int front;
int rear;
}QUEUE,*PQUEUE;
void init(PQUEUE);
bool en_queue(PQUEUE,int);
void traverse_queue(PQUEUE);
bool full_queue(PQUEUE);
bool out_queue(PQUEUE,int *);
bool empty_queue(PQUEUE);
bool empty_queue(PQUEUE pQ){
if(pQ->front ==pQ->rear){
return true;
}else{
return false;
}
}
bool out_queue(QUEUE*pQ,int *pVal){
if(empty_queue(pQ)){
return false;
}else{
*pVal = pQ->pBase[pQ->front];
pQ->front = pQ->front+1;
}
}
bool full_queue(PQUEUE pQ){
if((pQ->rear +1)%6 == pQ->front){
return true;
}else{
return false;
}
}
void init(PQUEUE pQ){
pQ->pBase = (int *)malloc(sizeof(int)*6);
pQ->front = 0;
pQ->rear = 0;
}
bool en_queue(PQUEUE pQ,int val){
if(full_queue(pQ)){
return false;
}else{
pQ->pBase[pQ->rear] = val;
pQ->rear = (pQ->rear+1) % 6;
return true;
}
}
void traverse_queue(PQUEUE pQ){
int i = pQ->front;
while(i!=pQ->rear){
printf("%d ",pQ->pBase[i]);
i = (i+1)%6;
}
}
int main(void){
QUEUE Q;
int val;
init(&Q);
en_queue(&Q,1);
en_queue(&Q,2);
en_queue(&Q,3);
en_queue(&Q,4);
en_queue(&Q,5);
en_queue(&Q,6);
en_queue(&Q,7);
en_queue(&Q,8);
traverse_queue(&Q);
if(out_queue(&Q,&val)){
printf("出隊 %d\n",val);
}else{
printf("失敗\n");
}
traverse_queue(&Q);
return 0;
}
總結
這個迴圈佇列,只要理解迴圈是咋弄的就很簡單了哈