队列的链式存储结构:只能尾进头出的单链表也叫链队列。(队列的特点:先进先出)
与顺序存储结构一样有front指针和rear指针,只不过front指向头结点,rear指向最后一个结点。
当front指针和rear指针都指向头结点时,链表为空。
链队列的结构代码:
typedef struct QNode
{
type data;
struct QNode *next;
}QNode , *QueuePtr;
typedef struct
{
QueuePtr front,rear;
}LinkQueue;
入队操作:插入元素s到队尾
第一步:让s指向空
第二步:把s接到rear的下一位。
第三步:让rear指向s
入队结构代码:
Status EnQueue(LinkQueue *Q , type e)
{ // 动态分配内存
QueuePtr s= (QueuePtr)malloc(sizeof(QNode));
if( !s ) // 如果内存分配失败,抛出异常
exit(OVERFLOW);
s->next=NULL; // 让s的指针域指向空
Q->rear->next=s; // 把s接到rear后面
Q->rear=s; // 把s赋给rear
return OK;
}
出队操作:让第一个结点a1出队并释放
第一步:把a1存入结点p
第二步:让头结点的指针域指向a2
第三步:释放p
若链表只有一个结点a1,则需将rear指向头结点。
出队结构代码:
Status DeQueue(LinkQueue *Q , type *e)
{
QueuePtr p;
if(Q->front==Q->rear) // 判断队列是否为空
return ERROR;
p=Q->front->next; // 把队头存入p
*e=p->data; // 把队头的数据存入e
// 头指针指向第二个元素
Q->front->next=p->next;
if(Q->rear==p) // 如果只有一个元素
Q->rear=Q->front; //rear指向头结点
free(rear); // 释放第一个结点
return OK;
}
总结:
在可以确定队列长度最大值的情况下,建议使用循环队列,若无法预估队列长度时,建议使用链队列。