概述
队列:只允许在一段进行插入删除操作,而在另一端进行删除操作的线性表。
队列是一种先进先出(FIFO)的线性表,允许插入的一端为队尾,允许插入的一端为队头。
循环队列
头尾相接的顺序存储结构为循环队列。
为防止溢出,通常保留一个空闲单元在队满时。
队满的条件:
(队尾 + 1) %队列长度 = 队头
通用的队长值为:
(队尾 - 队头 + 队列长度) % 队列长度
C定义
typedef int QElemType;
typedef struct
{
QElemType data[MAXSIZE];
int front;
int rear;
}SqQueue;
入队操作
int EnQueue(SqQueue *Q, QElemType e)
{
if ((Q->rear + 1) % MAXSIZE == Q->front) {
return 0;
}
Q->data[Q->rear] = e;
Q->rear = (Q->rear + 1) % MAXSIZE;
return 1;
}
出队操作
int DeQueue(SqQueue *Q, QElemType *e)
{
if (Q->rear == Q->front) {
return 0;
}
*e = Q->data[Q->front];
Q->front = (Q->front + 1) % MAXSIZE;
return 1;
}
链队列
特殊的单链表:尾进头出
C定义
typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode, *QueuePtr;
typedef struct {
QueuePtr front,rear;
}LinkQueue;
入队操作
int EnLinkQueue(LinkQueue *Q, QElemType e)
{
QueuePtr s = (QueuePtr)malloc(sizeof(QNode));
s->data = e;
s->next = NULL;
Q->rear->next = s;
Q->rear = s;
return 1;
}
出队操作
int DeLinkQueue(LinkQueue *Q, QElemType *e)
{
QueuePtr p;
if (Q->front == Q->rear) {
return 0;
}
p = Q->front->next;
*e = p->data;
Q->front->next = p->next;
if (Q->rear == p) {
Q->rear = Q->front;
}
free(p);
return 1;
}
总结
同大多数顺序和链式数据结构一样,如果队列长度在预知可控范围内,推荐使用循环队列;
如果不能控制队列长度,则推荐使用链式队列。