队列
概述
队列(Queue) 是一种遵循**先进先出(First-In-First-Out, FIFO)**原则的动态集合。最先入队(enqueue)的元素最先出队(dequeue),类似于在超市收银台排队——先到者先接受服务。
定义
队列(Queue)
队列 是一个支持以下操作的动态集合,维护两个属性:
- :指向队首元素(下一个被移除的元素)。
- :指向下一个新元素将被插入的位置。
操作定义:
- :;若 ,则 ;否则 。
- :若队列为空则报错 underflow;;若 ,则 ;否则 ;返回 。
队列使用数组 实现,通过**循环数组(circular array)**技巧避免元素出队后数组前端的浪费空间。
核心性质
- FIFO 原则:元素的出队顺序与入队顺序严格一致。
- 操作复杂度:、 均为 时间。
- 循环数组:通过取模运算(或条件判断)将 和 在 到 之间循环,使数组空间被重复利用。
- 容量限制:当队列填满( 且队列非空)时发生溢出。
循环数组工作原理
数组 Q[1..6],初始 head=1, tail=1(空队列)
Enqueue(a): [a, _, _, _, _, _] head=1, tail=2
Enqueue(b): [a, b, _, _, _, _] head=1, tail=3
Enqueue(c): [a, b, c, _, _, _] head=1, tail=4
Dequeue()→a: [_, b, c, _, _, _] head=2, tail=4
Enqueue(d): [_, b, c, d, _, _] head=2, tail=5
Enqueue(e): [_, b, c, d, e, _] head=2, tail=6
Enqueue(f): [f, b, c, d, e, _] head=2, tail=1 ← tail 回绕到数组头部
操作示例
| 操作 | 队列内容(head→tail) | head | tail |
|---|---|---|---|
| 初始 | — | 1 | 1 |
| Enqueue(4) | 4 | 1 | 2 |
| Enqueue(1) | 4, 1 | 1 | 3 |
| Dequeue() → 4 | 1 | 2 | 3 |
| Enqueue(3) | 1, 3 | 2 | 4 |
章节扩展
第10章:基于数组的实现
队列与栈同属第10章中”简单的基于数组的数据结构”。队列的关键设计难点在于:元素从头部移除后,如何高效利用释放的空间。CLRS 采用循环数组方案,通过让 和 指针在数组边界回绕,实现 的入队和出队操作。
队列在算法中广泛用于:广度优先搜索(BFS)、任务调度、缓冲区管理等场景。
第20章:基本图算法
BFS使用FIFO队列实现层序遍历:发现白色顶点时将其着灰色并入队,处理时出队并探索邻接顶点。队列保证了同层顶点先于下层顶点被处理,这是BFS最短路径性质的基础。
第24章:最大流
Edmonds-Karp算法使用BFS在残差网络中寻找最短(边数最少)增广路径。BFS的FIFO队列保证了每次找到的增广路径是最短的,从而使算法在 O(VE²) 时间内终止。