佇列

佇列，又稱為佇列（queue），計算機科學中的一種抽象資料型別，是先進先出（FIFO, First-In-First-Out）的線性表。在具體應用中通常用連結串列或者陣列來實現。佇列只允許在後端（稱為 rear）進行插入操作，在前端（稱為 front）進行刪除操作。

佇列的操作方式和堆疊類似，唯一的區別在於佇列只允許新資料在後端進行新增。

單鏈佇列

單鏈佇列使用連結串列作為基本資料結構，所以不存在偽溢位的問題，佇列長度也沒有限制。但插入和讀取的時間代價較高

1.1 儲存結構

/ c3-2.h 單鏈佇列－－佇列的鏈式儲存結構 /

typedef struct QNode

{

	QElemType data;

	struct QNode *next;

} QNode,*QueuePtr;

typedef struct

{QueuePtr front,rear; / 隊頭、隊尾指標 /} LinkQueue;

1.2 基本操作

/ bo3-2.c 鏈佇列 (儲存結構由 c3-2.h 定義) 的基本操作 (9 個) /

void InitQueue (LinkQueue *Q)

{	/ 構造一個空佇列 Q /

	(Q).front=(Q).rear=(QueuePtr) malloc (sizeof (QNode));

	if (!(*Q).front)

		exit (OVERFLOW);

	(*Q).front->next=NULL;

}

void DestroyQueue (LinkQueue *Q)

{/ 銷燬佇列 Q (無論空否均可) /

	while ((*Q).front)

	{(Q).rear=(Q).front->next;

		free ((*Q).front);

		(Q).front=(Q).rear;

	}

}

void ClearQueue (LinkQueue *Q)

{	/ 將 Q 清為空佇列 /

	QueuePtr p,q;

	(Q).rear=(Q).front;

	p=(*Q).front->next;

	(*Q).front->next=NULL;

	while (p)

	{

		q=p;

		p=p->next;

		free (q);

	}

}

Status QueueEmpty (LinkQueue Q)

{	/ 若 Q 為空佇列，則返回 TRUE，否則返回 FALSE /

	if (Q.front->next==NULL)

		return TRUE;

	else

		return FALSE;

}

int QueueLength (LinkQueue Q)

{	/ 求佇列的長度 /

	int i=0;

	QueuePtr p;

	p=Q.front;

	while (Q.rear!=p)

	{

		i++;

		p=p->next;

	}

	return i;

}

Status GetHead_Q (LinkQueue Q,QElemType e) / 避免與 bo2-6.c 重名 */

{	/ 若佇列不空，則用 e 返回 Q 的隊頭元素，並返回 OK，否則返回 ERROR /

	QueuePtr p;

	if (Q.front==Q.rear)

		return ERROR;

	p=Q.front->next;

	*e=p->data;

	return OK;

}

void EnQueue (LinkQueue *Q,QElemType e)

{	/ 插入元素 e 為 Q 的新的隊尾元素 /

	QueuePtr p=(QueuePtr) malloc (sizeof (QNode));

	if (!p) / 儲存分配失敗 /

		exit (OVERFLOW);

	p->data=e;

	p->next=NULL;

	(*Q).rear->next=p;

	(*Q).rear=p;

}

Status DeQueue (LinkQueue Q,QElemType e)

{	/ 若佇列不空，刪除 Q 的隊頭元素，用 e 返回其值，並返回 OK，否則返回 ERROR /

	QueuePtr p;

	if ((Q).front==(Q).rear)

		return ERROR;

	p=(*Q).front->next;

	*e=p->data;

	(*Q).front->next=p->next;

	if ((*Q).rear==p)

		(Q).rear=(Q).front;

	free (p);

	return OK;

}

void QueueTraverse (LinkQueue Q,void (*vi)(QElemType))

{/ 從隊頭到隊尾依次對佇列 Q 中每個元素呼叫函式 vi /

	QueuePtr p;

	p=Q.front->next;

	while (p)

	{vi (p->data);

		p=p->next;

	}

	printf ("\n");

}

迴圈佇列

迴圈佇列可以更簡單防止偽溢位的發生，但佇列大小是固定的。

// 佇列的順序儲存結構 (迴圈佇列)

define MAX_QSIZE 5 // 最大佇列長度 + 1

typedef struct {

int *base; // 初始化的動態分配儲存空間

int front; // 頭指標，若佇列不空，指向佇列頭元素

int rear; // 尾指標，若佇列不空，指向佇列尾元素的下一個位置

} SqQueue;

// 構造一個空佇列 Q

SqQueue Q_Init {SqQueue Q = (SqQueue*) malloc (sizeof (SqQueue));

// 儲存分配失敗

if (!Q){exit (OVERFLOW);

}

Q->base = (int ) malloc (MAX_QSIZE sizeof (int));

// 儲存分配失敗

if (!Q->base){exit (OVERFLOW);

}

Q->front = Q->rear = 0;

return Q;

}

// 銷燬佇列 Q，Q 不再存在

void Q_Destroy (SqQueue *Q) {if (Q->base)

free (Q->base);

Q->base = NULL;

Q->front = Q->rear = 0;

free (Q);

}

// 將 Q 清為空佇列

void Q_Clear (SqQueue *Q) {Q->front = Q->rear = 0;

}

// 若佇列 Q 為空佇列，則返回 1；否則返回 - 1

int Q_Empty (SqQueue Q) {if (Q.front == Q.rear) // 佇列空的標誌

return 1;

else

return -1;

}

// 返回 Q 的元素個數，即佇列的長度

int QLength (SqQueue Q) {return (Q.rear - Q.front + MAXQSIZE) % MAX_QSIZE;

}

// 若佇列不空，則用 e 返回 Q 的隊頭元素，並返回 OK；否則返回 ERROR

int Q_GetHead (SqQueue Q, int &e) {if (Q.front == Q.rear) // 佇列空

return -1;

e = Q.baseQ.front;

return 1;

}

// 列印佇列中的內容

void Q_Print (SqQueue Q) {

int p = Q.front;

while (Q.rear != p) {cout rear + 1) % MAX_QSIZE == Q->front) // 佇列滿

return -1;

Q->baseQ->rear = e;

Q->rear = (Q->rear + 1) % MAX_QSIZE;

return 1;

}

// 若佇列不空，則刪除 Q 的隊頭元素，用 e 返回其值，並返回 1；否則返回 - 1

int Q_Poll (SqQueue *Q, int &e) {if (Q->front == Q->rear) // 佇列空

return -1;

e = Q->baseQ->front;

Q->front = (Q->front + 1) % MAX_QSIZE;

return 1;

}

陣列佇列

define MAX_QSIZE 10 // 最大佇列長度 + 1

// 陣列佇列的儲存結構

struct Queue {

int ArrayMAX_QSIZE; // 陣列空間大小

int front; // 隊頭

int rear; // 隊尾

int length; // 佇列長度

};

// 構造一個空佇列 Q

Queue Q_Init {Queue Q = (Queue*) malloc (sizeof (Queue));

if (!Q){

// 儲存分配失敗

exit (OVERFLOW);

}

// 初始化

Q->front = Q->rear = Q->length = 0;

return Q;

}

// 將 Q 清為空佇列

void Q_Clear (Queue *Q) {

// 清除頭尾下標和長度

Q->front = Q->rear = Q->length = 0;

}

// 入列

int Q_Put (Queue *Q, int x) {

// 如果當前元素數量等於最大數量 返回 -1

if (Q->rear + 1 == MAX_QSIZE) {return -1;}

Q->ArrayQ->rear = x;

Q->rear = Q->rear + 1;

//length + 1

Q->length = Q->length + 1;

return 1;

}

// 出列

int Q_Poll (Queue *Q) {

// 如果當前元素數量等於最大數量 返回 -1

if (Q->front + 1 == MAX_QSIZE)

return -1;

int x = Q->ArrayQ->front;

Q->front = Q->front + 1;

// 移出後減少 1

Q->length = Q->length - 1;

return x;

}