1. 程式人生 > >佇列(連結串列)

佇列(連結串列)

佇列是具有兩個特殊屬性的連結串列。第一,新項只能新增到連結串列的末尾。第二,只能從連結串列的開頭移除項。是一種“先進先出”的資料形式。

佇列的操作有:初始化佇列為空,確定佇列為空,確定佇列已滿,確定佇列中的項數,在佇列末尾新增項,在佇列開頭刪除項或返回該項的值以及清空佇列。

運用連結串列表示佇列的好處是,我們只需兩個指標,一個指向隊首,一個指向隊尾即可。

首先考慮初始化,因為涉及該佇列的型別,所以應以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);
}