讲师中心 微信公众号
AI工具推荐 视频效率加速

C++ deque怎么用 C++双端队列容器底层结构详解【容器】

陌瑶姑娘_7674

陌瑶姑娘_7674

发布时间:2026-02-03 14:11:29

|

626人浏览过

|

来源于php中文网

原创

deque底层是分段连续空间,由多个固定缓冲区和中央映射数组组成,支持O(1)均摊头尾操作与O(1)随机访问,但缓存局部性差、迭代器非裸指针、内存不连续。

c++ deque怎么用 c++双端队列容器底层结构详解【容器】

deque 的底层结构不是链表,也不是普通数组

很多人看到“双端队列”就默认是链表实现,或者以为和 vector 一样用一块连续内存 —— 这两种理解都错。deque 底层典型实现是**分段连续空间**:由多个固定大小的缓冲区(通常 512 字节或按元素类型对齐)组成,用一个中央映射数组(map,本质是动态数组)来记录每个缓冲区的起始地址。这使得头尾插入/删除为 O(1) 均摊,随机访问为 O(1)(但常数比 vector 大),中间插入仍是 O(n)。

关键点:

  • deque 迭代器不是裸指针,而是封装了缓冲区切换逻辑的类,因此不支持 int* 那样的算术运算自由度(比如 *(it + n) 合法,但 it + n 可能跨缓冲区,需查 map)
  • 迭代器失效规则比 vector 宽松:只有在头/尾插入导致扩容 map 或新增缓冲区时,才可能使所有迭代器失效;而 vector 一次 push_back 就可能让全部迭代器失效
  • 内存不连续 → 缓存局部性差,遍历性能通常不如 vector,尤其在大量小对象场景下

什么时候该用 deque 而不是 vector 或 list

选 deque 不是因为它“更通用”,而是它在特定模式下有不可替代性:

  • 高频头插/头删 + 随机访问:比如实现滑动窗口、任务队列的头部优先调度、解析器中 token 缓冲区
  • 需要稳定迭代器(不希望因插入导致大量迭代器失效):例如你持有多个指向不同位置的 deque::iterator,且频繁在两端增删,deque 比 vector 更安全
  • 避免 list 的指针开销和缓存灾难:如果你不需要 list 的 O(1) 中间插入,但又受不了 vector 的头插开销,deque 是折中解
  • 别用它替代 vector 做纯尾部操作:此时 vector 内存紧凑、访问快、构造/析构更轻量

常见误用与崩溃点

以下写法看似合理,实则危险:

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

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

  • 把 deque 迭代器传给期望裸指针的 C API:例如 std::sort(deq.begin(), deq.end(), ...) 合法,但 qsort(*deq.begin(), ...) 会崩 —— deque::iterator 不是 T*,不能解引用后取地址当连续块用
  • 假设 &deq[0] 到 &deq[deq.size()-1] 是连续内存:这是错的,&deq[i] 和 &deq[i+1] 可能在不同缓冲区,std::memcmp 或 memcpy 整块拷贝会出错
  • 在多线程中只加锁头尾操作却忽略迭代器有效性:虽然头尾操作本身线程安全(无数据竞争),但若另一线程正在 resize 导致 map 重分配,你持有的迭代器可能已悬空
  • 用 deque<bool>:标准库对 deque<bool> 没有特化,它不会像 vector<bool> 那样位压缩,反而因分段结构更浪费空间

一个真实可用的滑动窗口示例

用 deque 维护窗口内最大值索引(单调队列),体现其头删、尾删、尾插三者高效的特点:

deque<int> dq; // 存储 nums 下标,保证 nums[dq.front()] 是当前窗口最大值
for (int i = 0; i < nums.size(); ++i) {
    // 清理过期下标(窗口左边界)
    if (!dq.empty() && dq.front() <= i - k) dq.pop_front();
    // 维护递减性:比 nums[i] 小的尾部元素全扔掉
    while (!dq.empty() && nums[dq.back()] < nums[i]) dq.pop_back();
    dq.push_back(i);
    if (i >= k - 1) result.push_back(nums[dq.front()]);
}

这里每轮最多一次 pop_front、多次 pop_back、一次 push_back,全部是 O(1) 均摊,且需随机访问 nums[dq.back()] —— 换成 list 就没法高效取尾部值,换成 vector 头删代价太高。

真正难的是理解“分段连续”带来的行为边界:它既不是纯数组,也不是纯链表,很多直觉在这里会失效。用之前,先问自己——我是否真的需要两端快速增删 + 随机访问?如果不是,大概率 vector 更合适。

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

相关专题

更多
sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

1138

2023.09.04

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

13926

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

1645

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

3817

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

5981

2024.03.01

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

13926

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

1645

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

3817

2023.12.21

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

0

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn