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