链队列(Linked Queue)是一种基于链表实现的队列结构。与顺序队列不同,链队列的存储空间是动态分配的,因此不需要预先定义队列的大小。链队列的每个结点包含数据域和指针域,队列的头指针指向头结点,尾指针指向最后一个结点。
以下是链队列的相关判断条件的详细罗列:
1.判断队列是否为空
条件:队列的头指针front和尾指针rear都指向头结点。
代码实现:
Cbool IsEmpty(LinkQueue Q) { return Q.front == Q.rear; }解释:
- 当
front == rear时,队列中没有元素,队列为空。
2.判断队列是否为满
条件:链队列的存储空间是动态分配的,理论上不会满。
代码实现:
Cbool IsFull(LinkQueue Q) { return false; // 链队列不会满 }解释:
- 链队列的存储空间是动态分配的,因此不会出现队列满的情况。
3.计算队列的长度
条件:遍历队列中的结点,统计结点数量。
代码实现:
Cint QueueLength(LinkQueue Q) { int length = 0; QueueNode *p = Q.front->next; // 从第一个结点开始 while (p != NULL) { // 遍历队列 length++; p = p->next; } return length; }解释:
- 通过遍历队列中的结点,统计结点数量,即为队列的长度。
4.入队操作的条件
条件:链队列的存储空间是动态分配的,因此不需要判断队列是否为满。
代码实现:
CStatus EnQueue(LinkQueue &Q, QElemType e) { QueueNode *newNode = (QueueNode*)malloc(sizeof(QueueNode)); // 创建新结点 if (!newNode) { return ERROR; // 内存分配失败 } newNode->data = e; // 设置新结点的数据域 newNode->next = NULL; // 新结点的指针域置为NULL Q.rear->next = newNode; // 将新结点插入队尾 Q.rear = newNode; // 更新尾指针 return OK; }解释:
- 如果内存分配成功,则将新结点插入队尾,并更新尾指针。
5.出队操作的条件
条件:队列不为空,即front != rear。
代码实现:
CStatus DeQueue(LinkQueue &Q, QElemType &e) { if (Q.front == Q.rear) { return ERROR; // 队列为空,无法出队 } QueueNode *p = Q.front->next; // 临时指针指向队头结点 e = p->data; // 取出队头元素 Q.front->next = p->next; // 将头指针指向下一个结点 if (Q.rear == p) { // 如果队列中只有一个元素 Q.rear = Q.front; // 更新尾指针 } free(p); // 释放队头结点的内存 return OK; }解释:
- 如果队列不为空,则取出队头元素,并将头指针指向下一个结点。
- 如果队列中只有一个元素,则更新尾指针。
6.队列的初始化
条件:创建头结点,并将头指针和尾指针都指向头结点。
代码实现:
CStatus InitQueue(LinkQueue &Q) { Q.front = Q.rear = (QueueNode*)malloc(sizeof(QueueNode)); // 创建头结点 if (!Q.front) { exit(OVERFLOW); // 内存分配失败 } Q.front->next = NULL; // 头结点的指针域置为NULL return OK; }解释:
- 初始化时,队列为空,因此头指针和尾指针都指向头结点。
7.队列的销毁
条件:释放队列中所有结点的内存,包括头结点。
代码实现:
CStatus DestroyQueue(LinkQueue &Q) { while (Q.front != Q.rear) { // 遍历队列 QueueNode *p = Q.front->next; // 临时指针指向队头结点 Q.front->next = p->next; // 将头指针指向下一个结点 if (Q.rear == p) { // 如果队列中只有一个元素 Q.rear = Q.front; // 更新尾指针 } free(p); // 释放队头结点的内存 } free(Q.front); // 释放头结点的内存 Q.front = Q.rear = NULL; // 头指针和尾指针置为NULL return OK; }解释:
- 销毁队列时,释放队列中所有结点的内存,包括头结点。
总结
链队列的关键判断条件如下:
- 队列空:
front == rear - 队列满:链队列不会满
- 队列长度:遍历队列中的结点,统计结点数量
- 入队条件:链队列的存储空间是动态分配的,因此不需要判断队列是否为满
- 出队条件:队列不为空
通过以上判断条件,可以确保链队列的正确操作。