1. 程式人生 > >資料結構(三)--迴圈佇列

資料結構(三)--迴圈佇列

迴圈佇列的基本操作

剛把資料結構裡面的佇列學習了一下,主要是對迴圈佇列的基本操作進行了瞭解,主要是想明白,迴圈佇列的迴圈是咋實現的,就好了,然後把入隊和出隊,判斷是否是空,和判斷是否為滿的弄懂就搞清楚迴圈隊列了。

佇列

這裡寫圖片描述
如圖所示,佇列是一種可以實現“先進先出”的儲存結構,哪一個節點元素先進來,它最先出去,然後如果想繼續加入節點,就在隊伍的最後面加入。
佇列分為鏈式佇列(用連結串列實現的)和靜態佇列(也就是迴圈佇列),在這篇部落格裡主要講的是迴圈佇列的基本操作。

迴圈佇列

這裡寫圖片描述
迴圈佇列是靠陣列來實現的,就是如圖所示一樣的哈,想一條蛇,收尾相連,具體如何收尾相連,就是靠很簡單的取餘來實現的哈,對陣列的長度進行取餘,就可以迴圈了哈。//如果這裡不懂,看下面,繼續講解的哈。

引數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;
} 

總結

這個迴圈佇列,只要理解迴圈是咋弄的就很簡單了哈