C++怎么使用deque C++双端队列容器操作【基础】

5次阅读

deque 初始化后不可直接下标访问,应使用初始化列表或带参构造;头部操作用 push_front/pop_front;首尾增删迭代器不失效,中间操作则全部失效;适用频繁头尾增删场景,随机访问和内存紧凑性不如vector。

C++怎么使用deque C++双端队列容器操作【基础】

deque 的初始化和常见构造方式

直接用 std::deque 时,最常踩的坑是误以为它和 vector 一样默认初始化后能直接用下标访问——其实不行,空 dequeoperator[] 是未定义行为。

  • 安全初始化:用 std::deque<int> dq = {1, 2, 3};</int>std::deque<int> dq(5, 0);</int>(构造 5 个 0)
  • 避免 std::deque<int> dq; dq[0] = 1;</int> —— 这会崩溃或静默出错
  • 如果要预留空间,用 dq.resize(n),不是 reserve()deque 没有 reserve 成员函数

在头部/尾部高效增删元素

deque 的核心价值就是两端 O(1) 插入删除,但得用对函数。很多人写 push_back 很顺,却在头部操作时绕弯子。

  • 头部插入:用 dq.push_front(x),不是 dq.insert(dq.begin(), x)(后者虽可行但更慢)
  • 尾部删除:用 dq.pop_back(),别写 dq.erase(--dq.end())
  • 注意:pop_front()pop_back() 不返回值,想获取再删要用 dq.front() + pop_front() 组合
  • 大量头插场景下,dequevector 稳定;但若只在尾部操作,vector 通常更快且内存更紧凑

迭代器失效规则和遍历时的陷阱

deque 迭代器比 vector 更“耐操”,但不是完全免疫失效。关键看操作位置和类型。

  • 仅在首尾增删:所有现存迭代器、引用、指针都有效(这是它和 vector 最大区别)
  • 中间插入/删除(如 insert(pos, x)erase(pos)):会导致所有迭代器失效(包括 begin()/end()
  • 遍历时别边循环pop_front() 还用 it++:应改用 while (!dq.empty()) { auto x = dq.front(); dq.pop_front(); }
  • 不要对 deque 做跨块指针算术(比如 &dq[10] - &dq[0]),结果不可靠——它内部是分段连续存储

和 vector 的性能与适用边界怎么选

deque 不是因为“双端队列听起来高级”,而是具体场景里它真能解决问题。

立即学习C++免费学习笔记(深入)”;

  • 需要频繁在头部插入/删除,且元素类型不支持移动(或移动代价高):优先 deque
  • 需要随机访问且下标使用密集(如算法中反复 dq[i]):vector 通常更快,缓存局部性更好
  • 内存占用敏感(嵌入式、大量小对象):deque 有额外指针开销,每块还可能有填充,实际内存更大
  • 标准库算法兼容性:所有接受 RandomAccessIterator 的算法(如 std::sort)都能用 deque,但实测性能可能不如 vector,尤其数据量大时

真正容易被忽略的是:dequesize() 是 O(1),但某些老编译器或 debug 模式下可能被实现为 O(n),如果对性能极端敏感,建议实测验证。

text=ZqhQzanResources