版權聲明:轉載請附上文章地址https://blog.csdn.net/qq_42672839
1.隊列的概念
只允許在一端插入數據操作,在另一端進行刪除數據操作的特殊線性表;進行插入操作的一端稱爲隊尾(入隊列),進行刪除操作的一端稱爲隊頭(出隊列);隊列具有先進先出(FIFO)的特性。
順序存儲就是用數組實現,比如有一個n個元素的隊列,數組下標0的一端是隊頭,入隊操作就是通過數組下標一個個順序追加,不需要移動元素,但是如果刪除隊頭元素,後面的元素就要往前移動,對應的時間複雜度就是O(n),性能自然不高。
jdk1.5中的阻塞隊列的操作如下:
add 增加一個元索 如果隊列已滿,則拋出一個IIIegaISlabEepeplian異常
remove 移除並返回隊列頭部的元素 如果隊列爲空,則拋出一個NoSuchElementException異常
element 返回隊列頭部的元素 如果隊列爲空,則拋出一個NoSuchElementException異常
offer 添加一個元素並返回true 如果隊列已滿,則返回false
poll 移除並返問隊列頭部的元素 如果隊列爲空,則返回null
peek 返回隊列頭部的元素 如果隊列爲空,則返回null
put 添加一個元素 如果隊列滿,則阻塞
take 移除並返回隊列頭部的元素 如果隊列爲空,則阻塞
3.隊列的邏輯
3.1 正常的一個順序隊列:
隊列的特性:先進先出,進入隊列從左邊進入,從右邊出隊列,所以A先進也是A先出
3.2 循環隊列
循環公式 tail=(tail+1)%array.Length;
什麼是循環隊列呢?就是有兩個指針,front指向隊頭,rear指向對尾元素的下一個位置,元素出隊時front往後移動,如果到了對尾則轉到頭部,同理入隊時rear後移,如果到了對尾則轉到頭部,這樣通過下標front出隊時,就不需要移動元素了。
隊列爲空時,front和rear相等,那隊列什麼時候判斷爲滿呢?按照循環操作rear依次後移,然後再從頭開始,也是出現rear和front相等時,隊列滿。這樣跟隊列空的情況就相同了,爲了區分這種情況,規定數組還有一個空閒單元時,就表示隊列已滿,因爲rear 可能在front後面,也可能循環到front前面,所以隊列滿的條件就變成了(rear+1)%maxsize = front ,同時隊列元素個數的計算就是(rear -front+maxsize)%maxsize。
隊列的鏈式存儲是在鏈表的基礎上,按照「先進先出」的原則操作數據元素。
例如,將隊列(A,B,C,D,E)依次入隊,然後再依次出隊。
代碼實現:(C語言)
#include <stdio.h> #include <stdlib.h> typedef struct QNode { int data; struct QNode *next; }QNode; QNode *initQueue() { QNode *queue = (QNode*)malloc(sizeof(QNode)); queue->next = NULL; return queue; } QNode *enQueue(QNode *rear, int data) { QNode *enElem = (QNode*)malloc(sizeof(QNode)); enElem->data = data; enElem->next = NULL; //使用尾插法向鏈隊列中添加數據元素 rear->next = enElem; rear = enElem; return rear; } void DeQueue(QNode *front, QNode *rear) { if (front->next == NULL) { printf("隊列爲空"); return ; } QNode *p = front->next; printf("%s", p->data); front->next = p->next; if (rear == p) { rear = front; } free(p); } int main() { QNode *queue, *front, *rear; queue = front = rear = initQueue(); //創建頭結點 //向鏈隊列中添加結點,使用尾插法添加的同時,隊尾指針需要指向鏈表的最後一個元素 rear = enQueue(rear, A); rear = enQueue(rear, B); rear = enQueue(rear, C); rear = enQueue(rear, D); rear = enQueue(rear, E); //入隊完成,所有數據元素開始出隊列 DeQueue(front, rear); DeQueue(front, rear); DeQueue(front, rear); DeQueue(front, rear); DeQueue(front, rear); DeQueue(front, rear); return 0; }
運行結果:
ABCDE隊列爲空