循環隊列的基本算法

1、介紹算法

正是由於隊列從隊頭刪除,從隊尾添加的特色,因此在使用數組來表現隊列時,元素的位置移動採用下標也即出隊front++或者入隊rear++的方式實現,這裏會體現出一個侷限性,資源空間的浪費。怎麼理解呢?數組

草圖所示:測試

圖示解釋:優化

一個數組隊列是滿的,arr[0]=a1 ,arr[1]=a2,arr[2]=a3,arr[3]=a4, 此時再將a5入隊列確定是失敗的。那麼能夠依次將a1,a2出隊列,此時能夠看到arr[0],arr[1]的位置空出來了。然而,因爲入隊的元素必須從隊尾進入,因此雖然有空餘的位置arr[0],arr[1], a5卻不能入隊列,這就形成了空間的浪費。在這裏能夠作一個優化,再也不單純的將位置移動也即front++或者rear++,而是採用一個簡單的算法來計算元素應該在數組中放置的位置,其實就是採用循環隊列來解決這個問題。循環隊列須要注意隊列已滿的判決條件,因爲尾指針始終指向尾元素的下一個位置,因此隊列始終會有一個空位置,其實未滿,可是這種狀況表明了已滿。ui

草圖所示:spa

 

循環隊列算法debug

出隊列:front = (front + 1) % maxSize 指針

入隊列:rear = (rear + 1) % maxSize code

空隊列:front == rearblog

滿隊列:front == (rear + 1) % maxSize

元素數:eleCount = (rear - front + maxSize) % maxSize

  

2、算法

#define MAXQSIZE         5 ///隊列的最大長度                                    
#define QUEUE_OVERFLOW  -1                                               
#define OK               1                                               
#define ERROR            0                                               
#define TRUE             1                                               
#define FALSE            0                                               
                                                                         
typedef int QElemType;                                                   
typedef int Status;                                                      
                                                                         
/// ----- 循環隊列 ------- 隊列的順序存儲結構                                         
                                                                         
typedef struct  {                                                        
    QElemType *base; //初始化的動態分配存儲空間,存儲元素                                 
    int front;       //隊頭指針,若隊列不空,指向隊列頭元素                                
    int rear;        //隊尾指針,若隊列不空,指向隊列尾元素的下一個位置                          
}SqQueue;                                                                
                                                                         
                                                                         
Status InitQueue(SqQueue &Q);             //初始化一個空的循環隊列                  
int    QueueLength(SqQueue Q);            //獲取隊元素個數                      
Status EnQueue(SqQueue &Q, QElemType e);  //把元素e從隊尾添加隊列中                 
Status DeQueue(SqQueue &Q, QElemType &e); //獲取隊列的頭元素,並取出元素值賦給e保存         

 

3、代碼

Status InitQueue(SqQueue &Q) {                                                    
                                                                                  
    ///初始化一個空的循環隊列                                                                
    Q.base = (QElemType *)malloc(MAXQSIZE * sizeof(QElemType));                   
    if (!Q.base) exit(QUEUE_OVERFLOW); //存儲分配失敗                                   
    Q.front = Q.rear = 0;                                                         
    cout<<"空隊列建立成功"<<endl;                                                        
    return  OK;                                                                   
}                                                                                 
                                                                                  
int QueueLength(SqQueue Q) {                                                      
                                                                                  
    ///獲取隊元素個數                                                                    
    int eleCount = (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;                      
    cout<<"隊列元素有:"<<eleCount<<""<<endl;                                          
    return eleCount;                                                              
                                                                                  
}                                                                                 
                                                                                  
Status EnQueue(SqQueue &Q, QElemType e){                                          
                                                                                  
    ///把元素e從隊尾添加隊列中                                                               
    if ((Q.rear + 1) % MAXQSIZE == Q.front) {                                     
        cout<<"隊列已滿"<<endl;                                                       
        return ERROR; //隊列已滿                                                      
    }                                                                             
    Q.base[Q.rear] = e;                                                           
    Q.rear = (Q.rear + 1) % MAXQSIZE;                                             
    cout<<"入隊的元素:"<<e<<",front = "<<Q.front<<",rear = "<<Q.rear<<endl;            
    return OK;                                                                    
}                                                                                 
                                                                                  
Status DeQueue(SqQueue &Q, QElemType &e){                                         
                                                                                  
    ///獲取隊列的頭元素,並取出元素值賦給e保存                                                       
    if(Q.front == Q.rear){                                                        
        cout<<"隊列已空"<<endl;                                                       
        return ERROR; //隊列已空                                                      
    }                                                                             
    e = Q.base[Q.front];                                                          
    Q.front = (Q.front + 1) % MAXQSIZE;                                           
    cout<<"出隊的元素:"<<e<<",front = "<<Q.front<<",rear = "<<Q.rear<<endl;            
    return OK;                                                                    
}                                                                                 

 

4、結果

測試: 

int main() {                                    
                                                
    //構建隊列                                      
    SqQueue Q;                                  
    if (InitQueue(Q)) {                         
        for (int i = 0; i < MAXQSIZE; ++i) {    
            //入隊列                               
            EnQueue(Q, i + 1);                  
        }                                       
    }                                           
                                                
    //獲取隊列元素個數                                  
    QueueLength(Q);                             
    cout<<endl;                                 
                                                
    for (int j = 0; j < 3; ++j) {               
        //出隊列                                   
        QElemType e;                            
        DeQueue(Q, e);                          
                                                
        //獲取隊列元素個數                              
        QueueLength(Q);                         
    }                                           
                                                
    return 0;                                   
}                                               

打印:

/Users/xiayuanquan/CLionProjects/cycleQueue/cmake-build-debug/cycleQueue
空隊列建立成功
入隊的元素:1,front = 0,rear = 1
入隊的元素:2,front = 0,rear = 2
入隊的元素:3,front = 0,rear = 3
入隊的元素:4,front = 0,rear = 4
隊列已滿
隊列元素有:4個

出隊的元素:1,front = 1,rear = 4
隊列元素有:3個
出隊的元素:2,front = 2,rear = 4
隊列元素有:2個
出隊的元素:3,front = 3,rear = 4
隊列元素有:1個

進程已結束,退出代碼 0
相關文章
相關標籤/搜索