佇列(連結串列)
佇列是具有兩個特殊屬性的連結串列。第一,新項只能新增到連結串列的末尾。第二,只能從連結串列的開頭移除項。是一種“先進先出”的資料形式。
佇列的操作有:初始化佇列為空,確定佇列為空,確定佇列已滿,確定佇列中的項數,在佇列末尾新增項,在佇列開頭刪除項或返回該項的值以及清空佇列。
運用連結串列表示佇列的好處是,我們只需兩個指標,一個指向隊首,一個指向隊尾即可。
首先考慮初始化,因為涉及該佇列的型別,所以應以Queue的地址作為引數:
void InitializeQueue(Queue *pq);
接下來測試改佇列是否為空或已滿:
int QueueIsFull(const Queue *pq);
int QueueIsEmpty(const Queue *pq);
返回佇列的項數:
int QueueItemCount(const Queue *pq);
在隊尾進行新增,我們可以通過返回值表示是否新增成功:
int EnQueue(Item item,Queue *pq)
刪除佇列的首項,可以這樣定義下面的原型:
int DeQueue(Item *pitem,Queue *pq)
清空佇列的函式原型如下:
void EmptyTheQueue(Queue *pq)。
Queue記憶體儲該佇列的首指標、尾指標和項數,Item為該佇列記憶體儲的資料型別。
我們以一個整數為佇列進行測試,所以應:
typedef int Item;
連結串列由節點組成,接下來定義節點:
typedef struct node
{
Item item;
struct node *next;
}Node;
佇列只需儲存首指標 、尾指標及項數,構成如下:
typedef strucct queue
{
Node *fronst; //指向佇列首項的指標
Node *rear; //指向佇列尾項的指標
int items ; //佇列中的項數
}
程式碼如下:
#include<stdio.h> #include<stdlib.h> typedef int Item; #define MAXQUEUE 10 //佇列中能儲存的最多項數 typedef struct node { Item item; struct node *next; }Node; typedef struct queue { Node *front; Node *rear; int items; //佇列中的項數 }Queue; void InitializeQueue(Queue * pq);//初始化佇列 int QueueIsFull(const Queue *pq);//檢查佇列是否已滿 int QueueIsEmpty(const Queue *pq);//檢查佇列是否為空 int QueueItemCount(const Queue *pq);//返回佇列中的項數 int EnQueue(Item item,Queue *pq);//在佇列末尾新增項 int DeQueue(Item *pitem,Queue *pq);//從佇列開頭刪除項 void EmptyTheQueue(Queue *pq);//清空佇列 /*前提:pq指向一個佇列*/ void InitializeQueue(Queue * pq) { pq->front = pq->front =NULL; //佇列為空即首項和尾項為NULL pq->items =0; //項數為0 } /*前提:pq指向已被初始化的佇列*/ int QueueIsFull(const Queue *pq) { return pq->items==MAXQUEUE; //佇列中的項數是否達到所能儲存的最大項 } /*前提:pq指向已被初始化的佇列*/ int QueueIsEmpty(const Queue *pq) { return pq->items==0; //佇列中是否已儲存 } /*前提:pq指向已被初始化的佇列*/ int QueueItemCount(const Queue *pq) { return pq->items; //返回pq的項數 } /*前提:pq指向已被初始化的佇列, item實在隊尾新增的項*/ int EnQueue(Item item,Queue *pq) { Node *pnew; if(QueueIsFull(pq)) //如果佇列已滿,不能新增 return 0; pnew=(Node *)malloc(sizeof(Node)); if(pnew==NULL) { printf("空間分配失敗"); exit(1); } pnew->item=item; pnew->next=NULL; if(QueueIsEmpty(pq)) //佇列為空往隊首新增 pq->front=pnew; else pq->rear->next=pnew; //佇列不為空往隊尾新增 pq->rear=pnew; pq->items++; //新增後項數增加 return 1; } /*前提:pq指向已被初始化的佇列*/ int DeQueue(Item *pitem,Queue *pq) { if(QueueIsEmpty(pq)) //佇列為空 return 0; Node *pnew=pq->front; //記錄隊首 *pitem=pq->front->item; //返回隊首儲存的資料 pq->front=pq->front->next; //首指標後移 free(pnew); //釋放原隊首 pq->items--; //項數減一 if(pq->items==0) //佇列變空後,隊首、隊尾指標置NULL pq->rear=NULL; return 1; } /*前提:pq指向已被初始化的佇列*/ void EmptyTheQueue(Queue *pq) { Item pitem; while(!QueueIsEmpty(pq)) DeQueue(&pitem,pq); }