3.8队列的定义与队列的链式存储
1、队列的定义
队列 (Queue) 是另一种限定性的线性表,它只允许在表的一端插入元素,而在另一端删除元素,所以队列具有先进先出 (Fist In Fist Out,缩写为FIFO)的特性。
- 在队列中,允许插入的一端叫做队尾(rear);
- 允许删除的一端则称为队头(front)。
队列的抽象数据类型定义
ADT Queue
数据元素:可以是任意类型的数据,但必须属于同一个数据对象。
关系:队列中数据元素之间是线性关系。
基本操作:
- (1) InitQueue(&Q):初始化操作。设置一个空队列。
- (2) IsEmpty(Q):判空操作。若队列为空,则返回 TRUE,否则返回 FALSE。
- (3) IsFull(Q):判满操作。若队列为满,则返回 TRUE,否则返回 FALSE。
- (4) EnterQueue(&Q,x):进队操作。在队列 Q 的队尾插入 x。操作成 功,返回值为 TRUE,否则返回值为 FALSE。
- (5) DeleteQueue(&Q,&x):出队操作。使队列 Q 的队头元素出队,并 用 x 带回其值。操作成功,返回值为 TRUE,否则返回值为 FALSE。
- (6) GetHead(Q,&x):取队头元素操作。用 x 取得队头元素的值。操 作成功,返回 TRUE,否则返回值为 FALSE。
- (7) ClearQueue(&Q):队列置空操作。将队列 Q 置为空队列。
- (8) DestroyQueue(&Q): 队列销毁操作。释放队列的空间。
2、队列的表示和实现—链队列
链队列 用链表表示的队列简称为链队列。
为了操作方便,这里采用带头结点的链表 结构,并设置一个队头指针和一个队尾指针,如下图所示。
队头指针始终指向头结点,队尾指针指向当前最后一个元素。
空的链队列的队头指针和队尾指针均指向头结点。
链队列定义如下:
typedef struct Node
{
QueueElementType data; /*数据域*/
struct Node *next; /*指针域*/ }LinkQueueNode;
typedef struct
{
LinkQueueNode * front;
LinkQueueNode * rear;
}LinkQueue;
链队列的基本操作
(1) 初始化操作
int InitQueue(LinkQueue * Q)
{ /* 将 Q 初始化为一个空的链队列 */
Q->front=(LinkQueueNode *)malloc(sizeof(LinkQueueNode));
if(Q->front!=NULL)
{
Q->rear=Q->front;
Q->front->next=NULL;
return(TRUE);
}
else
return(FALSE); /* 溢出!*/
}
(2) 入队操作
int EnterQueue(LinkQueue *Q, QueueElementType x)
{ /* 将数据元素 x 插入到队列 Q 中 */
LinkQueueNode * NewNode;
NewNode=(LinkQueueNode * )malloc(sizeof(LinkQueueNode));
if(NewNode!=NULL)
{
NewNode->data=x;
NewNode->next=NULL;
Q->rear->next=NewNode;
Q->rear=NewNode;
return(TRUE);
}
else
return(FALSE); /* 溢出!*/
}
(3) 出队操作
int DeleteQueue(LinkQueue * Q, QueueElementType *x)
{ /* 将队列 Q 的队头元素出队,并存放到 x 所指的存储空间中 */
LinkQueueNode * p;
if(Q->front==Q->rear)
return(FALSE);
p=Q->front->next;
Q->front->next=p->next; /* 队头元素 p 出队 */
if(Q->rear==p) /* 如果队中只有一个元素 p,则 p 出队后成为空队 */
Q->rear=Q->front;
*x=p->data;
free(p); /* 释放存储空间 */
return(TRUE);
}