链队列的类型定义
在用户无法估计所用队列的长度时,宜采用链队列,其形式如下图,
与普通线性表不同的是,它定义了头尾两个指针。
普通的链表结点定义如下:
typedef struct Qnode
{
QElemType data;
struct Qnode* next;
}Qnode, *QueuePtr;
加入头尾指针的链队列定义如下:
typedef struct
{
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
}LinkQueue;
链队列运算指针变化情况如下图,
链队列的各种操作
- 链队列的初始化
Status InitQueue(LinkQueue& Q)
{
Q.front = Q.rear = new QueuePtr;
Q.front->next = NULL;
return OK;
}
- 销毁链队列
Status DestroyQueue(LinkQueue& Q)
{
while (Q.front)
{
p = Q.front->next;
delete Q.front;
Q.front = p;
}
}
- 将元素e入队
Status EnQueue(LinkQueue& Q, QElemType e)
{
p = new QueuePtr;
if (!p)
exit(OVERFLOW);
p->data = e; //创建一个新结点p
p->next = NULL;
Q.rear->next = p; //尾结点的指针域指向p
Q.rear = p; //修改尾指针为当前结点p
return OK;
}
- 链队列出队
Status DeQueue(LinkQueue& Q, QElemType& e)
{
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;
delete p; //删除队首结点
return OK;
}
这里有一种特殊情况,即队列中只有一个元素(队尾元素出队),此时当删除该元素时,尾指针也要指向头结点。
- 求链队的队头元素
Status GetHead(LinkQueue Q, QElemType& e)
{
if (Q.front == Q.rear)
return ERROR;
e = Q.front->next->data;
return OK;
}