目录
什么是假溢出?
如何解决?
链式队列的结构
出队举例:
总结
顺序队列(顺序存储的队列)会发生“假溢出”,这是它的一个典型问题。
什么是假溢出?
假溢出指的是:
队列的存储空间还有空闲位置,但由于队头指针已经移动,队尾指针到达了数组末尾,导致无法继续入队。
也就是说,逻辑上有空位,物理上却不能利用,举个例子
假设顺序队列用数组Q[5]存储:
下标: 0 1 2 3 4 ----------------- Q: A B C D E初始:
front = 0 rear = 5队列满。
现在连续出队两个元素:
出队 A、B 下标: 0 1 2 3 4 ----------------- Q: 空 C D E front = 2 rear = 5此时数组前面:
Q[0], Q[1]已经空出来了,如果继续入队F,按照普通顺序队列的规则:
rear = 5已经超过数组最大下标,因此认为“队满”。
但实际上:
Q[0]、Q[1]还有空间所以这就是假溢出。
如何解决?
常用方法:采用循环队列(推荐)让数组首尾相连:队尾到末尾后可以回到开头继续存储。
0 → 1 → 2 → 3 → 4 → 0移动元素:每次出队后把剩余元素向前移动,但效率低,时间复杂度高。
链式队列是指采用链式存储结构实现的队列,通常用单链表表示。它通过指针连接各个结点,不需要连续的存储空间。
链式队列的结构
一个链式队列通常设置两个指针:
- 队头指针 front:指向队头结点(出队位置)
- 队尾指针 rear:指向队尾结点(入队位置)
结构如下:
front rear ↓ ↓ [数据|next] → [数据|next] → [数据|null]出队举例:
原来的链式队列:
front ↓ [A] → [B] → [C] → NULL ↑ rear操作步骤:保存原 front 结点.front 后移:
p = front front = front->next此时:
front ↓ [B] → [C] → NULL ↑ rear释放原来的 A:
free(p)所以新的 front 就是原来 front 的下一个结点。
front 是一个指针变量,它自己有地址 &front
p 是一个指针变量,它自己有地址 &p
它们里面存的是节点的地址
总结
| 队列类型 | 会不会假溢出 |
|---|---|
| 普通顺序队列 | ✅ 会 |
| 循环队列 | ❌ 不会 |
| 链式队列 | ❌ 不会(只受内存限制) |
顺序队列存在“假溢出”问题,循环队列用于解决假溢出。