1.定義
隊列(queue)是只允許在一端進行插入操作,而在另一端進行刪除操作的線性表。
- 與棧相反,隊列是一種先進先出(First In First Out,FIFO)的線性表
- 與棧相同的是,隊列也是一種重要的線性結構,實現一個隊列同樣需要順序表或鏈表作為基礎
隊列
2.隊列的鏈式存儲結構
隊列既可以用鏈表實現,也可以用順序表實現。跟棧相反的是,棧一般我們用順序表來實現,而隊列我們常用鏈表來實現,簡稱為鏈隊列
typedef struct QNode{
ElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct LinkQueue{
QueuePtr front,rear;//隊頭、尾指針
}LinkQueue;
我們將隊頭指針指向鏈隊列的頭結點,而隊尾指針指向終端結點。(注:頭結點不是必要的,但我們加上后操作更方便)
隊列
空隊列時,front和rear都指向頭結點
空隊列
(1)創建一個隊列
創建一個隊列要完成兩個任務:
- 創建頭結點
- 將隊列的頭指針和尾指針都指向頭結點,生成空隊列
Status initQueue(LinkQueue *q){
q->front = (QueuePtr)malloc(sizeof(QNode));
if (!q->front) {
return ERROR;
}
q->rear = q->front;
q->rear->next = NULL;
return OK;
}
(2) 入隊列操作
入隊列操作
如圖所示,入隊列就是在隊尾插入一個新的結點
Status insertQueue(LinkQueue *q,ElemType e){
QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
if (!p) {
return ERROR;
}
p->data = e;
p->next = NULL;
q->rear->next = p;
q->rear = p;
return OK;
}
(3)出隊列操作
出隊列操作是將隊列中的第一個元素移出,隊頭指針不發生改變,改變頭結點的next指針即可
出隊列操作
如果原隊列只有一個元素,那么我們就應該處理一下隊尾指針,讓它指向頭結點
處理一個元素的情況
Status deleteQueue(LinkQueue *q,ElemType *e){
if (q->rear == q->front) {
//隊尾和隊頭指向相同,表示空隊列
return ERROR;
}
QueuePtr p = q->front->next;
//返回值
*e = p->data;
//頭結點指向下一個元素
q->front->next = p->next;
if (q->rear == p) {
//只有一個元素的隊列
q->rear = q->front;
}
free(p);
return OK;
}
(4)銷毀一個隊列
由于鏈隊列建立在內存的動態區,因此當一個隊列不再有用時應當把它及時銷毀掉,以免過多的占用內存空間
Status destroyQueue(LinkQueue *q){
while (q->front) {
QueuePtr p = q->front;
q->front = q->front->next;
free(p);
}
q->front = q->rear = NULL;
return OK;
}