“边权登场时 BFS 即失效:设 $s\to a$ 权 $10$、$s\to b$ 权 $1$、$b\to a$ 权 $1$,按边数算 $a$ 的“最短”是一条直达边,按权重却应绕行 $b$。…”
形式陈述 ​
双端队列(deque)是一种抽象数据类型,其状态是有限序列
空队列上的弹出必须由接口规定为错误、空结果或禁止调用。只使用 push_back 与 pop_front 时,它退化为 FIFO 队列;只在同一端压入和弹出时,它表现为栈。双端能力描述的是一条序列的两个端点,不是把两个互不相干的队列拼在一起。
循环数组实现维护容量
直觉 ​
普通队列把进入端和离开端固定下来,deque 则允许算法根据局部结构选择把候选放到哪一端、从哪一端取走。序列次序仍是唯一的;灵活性来自两端都是合法更新位置,而不是取消顺序。循环数组通过让下标在存储区末端回绕,复用前端弹出后留下的空间,避免每次移动所有剩余元素。
抽象接口不决定容器是否连续、迭代器会不会失效,也不保证中间插删或按下标访问。把某种语言标准库的 deque 实现特性当成定义,会把可移植的算法错误地绑定到一个容器布局。
例子与边界 ​
从空 deque 执行 push_back(a)、push_back(b)、push_front(c) 后,序列是 pop_back() 返回 pop_front() 返回
0–1 BFS 对权为
数组实现发生扩容时,单次操作需要复制
推论与应用 ​
Deque 统一覆盖 FIFO 与 LIFO 的端点行为,常用于工作窃取调度、回文扫描、0–1 BFS 和单调队列。选择实现时,应把算法实际需要的保证逐项对照:循环数组适合局部性与随机访问扩展,链式或分块结构适合稳定地址与避免整块搬迁;任何额外性质都应写在实现契约中。
与优先队列的差别尤其重要:deque 只能取当前首或尾,不能根据任意键选出全局最优元素。若算法正确性依赖“每次取最小距离”,需要的是优先队列;若只需在两种已知优先级之间把新元素放到不同端点,deque 才足够。
参考资料
- Thomas H. Cormen et al., Introduction to Algorithms, 4th ed., MIT Press, 2022, §10.1, stacks and queues.
- Kurt Mehlhorn and Peter Sanders, Algorithms and Data Structures: The Basic Toolbox, Springer, 2008, Ch. 3, sequences and queue implementations.