news 2026/4/23 1:00:45

STL deque 的详细特征

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STL deque 的详细特征

STL deque 的详细特征

  1. 基本特性
#include<deque>usingnamespacestd;deque<int>dq;// 声明一个int类型的双端队列

· 双端队列:允许在两端进行高效插入和删除
· 动态数组:支持随机访问,可以像数组一样通过下标访问
· 内存结构:分段连续存储,由多个固定大小的内存块组成

  1. 内存结构与实现原理

内部结构示意图

deque内存布局: [块1] → [块2] → [块3] → [块4] → [块5] ↓ ↓ ↓ ↓ ↓ [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] ↑front ↑back 每个块:固定大小(通常是512字节或容纳元素的内存对齐大小) 维护一个中央控制器(map):存储各个块的指针

关键特征

// 1. 分块存储// deque将元素存储在多个固定大小的内存块中// 当需要扩容时,分配新的内存块,而不是重新分配整个数组// 2. 随机访问复杂度 O(1)deque<int>dq={1,2,3,4,5};cout<<dq[2];// O(1) 访问// 3. 两端操作复杂度 O(1)dq.push_front(0);// O(1)dq.push_back(6);// O(1)dq.pop_front();// O(1)dq.pop_back();// O(1)
  1. 时间复杂度分析

操作 时间复杂度 说明
push_front() O(1) 平均分摊
push_back() O(1) 平均分摊
pop_front() O(1) 平均分摊
pop_back() O(1) 平均分摊
operator[] O(1) 随机访问
insert() O(n) 中间插入
erase() O(n) 中间删除
front()/back() O(1) 访问首尾

  1. 与 vector/list 的对比

性能对比

#include<deque>#include<vector>#include<list>#include<iostream>voidbenchmark(){// 1. 前端插入 - deque 最优deque<int>dq;vector<int>vec;list<int>lst;// push_front 测试for(inti=0;i<100000;++i){dq.push_front(i);// 快:O(1)lst.push_front(i);// 快:O(1)vec.insert(vec.begin(),i);// 慢:O(n)}}

详细对比表

特性 deque vector list
内存布局 分段连续 连续 不连续
随机访问 O(1) O(1) O(n)
前端插入 O(1) O(n) O(1)
后端插入 O(1) 分摊O(1) O(1)
中间插入 O(n) O(n) O(1)
内存开销 中等 低 高
缓存友好 中等 高 低
迭代器类型 随机访问 随机访问 双向

  1. 迭代器特征

迭代器特性

deque<int>dq={1,2,3,4,5};// 1. 随机访问迭代器autoit=dq.begin();it+=3;// 支持随机访问cout<<*it;// 输出4// 2. 迭代器失效规则dq.push_front(0);// 所有迭代器失效!dq.push_back(6);// 所有迭代器失效!// 3. 插入/删除中间元素it=dq.begin()+2;dq.insert(it,99);// it失效

迭代器失效情况

操作 迭代器失效情况
push_front() 所有迭代器失效
push_back() 所有迭代器失效
pop_front() 指向被删元素的迭代器失效
pop_back() 指向被删元素的迭代器失效
insert() 所有迭代器失效
erase() 被删位置之后的迭代器失效
resize() 所有迭代器失效

  1. 常用操作示例

基本操作

#include<deque>#include<iostream>#include<algorithm>voidbasic_operations(){deque<int>dq;// 1. 两端插入dq.push_back(10);// 后: 10dq.push_front(5);// 前: 5, 后: 10 → 5,10dq.emplace_back(15);// C++11: 5,10,15dq.emplace_front(0);// C++11: 0,5,10,15// 2. 访问元素cout<<"第一个元素: "<<dq.front()<<endl;// 0cout<<"最后一个元素: "<<dq.back()<<endl;// 15cout<<"第三个元素: "<<dq[2]<<endl;// 10cout<<"大小: "<<dq.size()<<endl;// 4// 3. 删除元素dq.pop_front();// 移除0 → 5,10,15dq.pop_back();// 移除15 → 5,10// 4. 中间操作dq.insert(dq.begin()+1,7);// 5,7,10dq.erase(dq.begin()+1);// 移除7 → 5,10// 5. 清空和检查dq.clear();cout<<"是否为空: "<<dq.empty()<<endl;// true}

高级用法

voidadvanced_usage(){// 1. 构造函数deque<int>dq1(5,100);// 5个100deque<int>dq2={1,2,3,4,5};// 初始化列表deque<int>dq3(dq2.begin(),dq2.begin()+3);// 复制部分// 2. 交换deque<int>a={1,2,3};deque<int>b={4,5,6};a.swap(b);// O(1)操作// 3. 调整大小deque<int>dq={1,2,3};dq.resize(5);// 变为: 1,2,3,0,0dq.resize(2);// 变为: 1,2dq.resize(4,99);// 变为: 1,2,99,99// 4. 容量相关deque<int>dq4;dq4.reserve(100);// ❌ deque没有reserve()!// 只能通过resize预先分配空间dq4.resize(100);// 分配100个元素空间}
  1. 实际应用场景

场景1:滑动窗口

// 滑动窗口最大值vector<int>maxSlidingWindow(vector<int>&nums,intk){deque<int>dq;// 存储下标vector<int>result;for(inti=0;i<nums.size();++i){// 移除窗口外的元素if(!dq.empty()&&dq.front()==i-k)dq.pop_front();// 维护单调递减队列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()]);}returnresult;}

场景2:任务队列

classTaskScheduler{private:deque<pair<int,string>>taskQueue;// 优先级, 任务名public:voidaddHighPriorityTask(string task){taskQueue.push_front({1,task});// 前端插入}voidaddLowPriorityTask(string task){taskQueue.push_back({0,task});// 后端插入}stringgetNextTask(){if(taskQueue.empty())return"";string task=taskQueue.front().second;taskQueue.pop_front();returntask;}};

场景3:回文字符串判断

boolisPalindrome(conststring&s){deque<char>dq;// 填充deque(忽略空格和大小写)for(charc:s){if(isalnum(c))dq.push_back(tolower(c));}// 两端比较while(dq.size()>1){if(dq.front()!=dq.back())returnfalse;dq.pop_front();dq.pop_back();}returntrue;}
  1. 性能优化技巧

优化建议

// 1. 使用emplace代替push(C++11及以上)deque<pair<int,string>>dq;dq.emplace_back(1,"test");// 避免临时对象构造// 等价于: dq.push_back(make_pair(1, "test"));// 2. 预先分配空间deque<int>dq;dq.resize(1000);// 如果知道大致大小,预先分配// 3. 批量操作使用assigndq.assign(100,0);// 100个0,比循环push_back快// 4. 避免频繁的中间插入删除// 如果需要频繁中间操作,考虑使用list// 5. 使用swap释放内存deque<int>dq;// ... 使用dq ...deque<int>().swap(dq);// 清空并释放内存
  1. 注意事项

常见陷阱

// 1. 迭代器失效问题deque<int>dq={1,2,3,4,5};autoit=dq.begin()+2;dq.push_front(0);// ❌ it失效!// cout << *it; // 未定义行为// 2. 没有capacity()和reserve()deque<int>dq;// dq.capacity(); // ❌ 没有这个函数// dq.reserve(100); // ❌ 没有这个函数// 3. 中间操作性能差for(inti=0;i<10000;++i){dq.insert(dq.begin()+dq.size()/2,i);// O(n) 很慢!}// 4. 内存不是完全连续int*ptr=&dq[0];// ptr + dq.size() 可能不指向有效内存!

最佳实践

  1. 优先使用deque的场景:
    · 需要双端队列功能
    · 既需要随机访问又需要两端操作
    · 不确定前端还是后端操作更频繁

  2. 选择vector的场景:
    · 主要在后端操作
    · 需要连续内存
    · 需要最高缓存友好性

  3. 选择list的场景:
    · 频繁在中间插入删除
    · 不需要随机访问
    · 需要稳定的迭代器

  4. C++11/14/17/20 新特性

// C++11: emplace, initializer_listdeque<int>dq={1,2,3,4,5};dq.emplace_front(0);// C++17: try_emplace, insert_or_assign (对于map)// deque本身变化不大// C++20: 范围构造vector<int>vec={1,2,3,4,5};deque<int>dq(vec.begin(),vec.end());// C++20: 概念约束template<typenameT>requiresstd::random_access_iterator<typenameT::iterator>voidprocess(T&container){// 只接受支持随机访问的容器}

总结:deque是STL中一个平衡了随机访问和两端操作性能的数据结构,适用于特定的使用场景,但需要注意其迭代器失效规则和内存特性。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 22:45:03

VDD_EXT低功耗设计指南:原理剖析与优化策略!

VDD_EXT的性能表现直接影响系统的电源完整性与能效比。在低功耗设计中&#xff0c;必须深入理解其供电机制、电压容限及动态响应特性&#xff0c;才能避免不必要的能量损耗。本文将从基础原理入手&#xff0c;系统梳理VDD_EXT的设计优化策略&#xff0c;为工程师提供实用参考。…

作者头像 李华
网站建设 2026/4/18 6:12:17

AI大模型学习全攻略:产品经理必看,程序员必备的实用指南

本文探讨AI大模型发展现状及对产品经理的影响&#xff0c;提供把握机遇的方法&#xff0c;包括技术理解、需求洞察、产品规划和跨团队协作。详细介绍学习路径&#xff1a;基础学习、编程技能、理论与实践、专业课程、社区参与和持续跟踪。同时提供学习路线、报告合集、经典书籍…

作者头像 李华
网站建设 2026/4/17 8:08:46

团队协作必备!SimpleMindMap + cpolar,思维导图随时共享

文章目录前言1. Docker一键部署思维导图2. 本地访问测试3. Linux安装Cpolar4. 配置公网地址5. 远程访问思维导图6. 固定Cpolar公网地址7. 固定地址访问前言 SimpleMindMap 是一款支持私有化部署的思维导图工具&#xff0c;能通过拖拽操作快速创建组织结构图、项目规划图等&…

作者头像 李华
网站建设 2026/4/20 7:51:50

【优化选址】基于遗传算法GA求解物流网络选址优化问题附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f34a;个人信条&#xff1a;格物致知,完整Matlab代码获取及仿真…

作者头像 李华
网站建设 2026/4/17 9:10:58

【Go/Python/Java】基础语法+核心特性对比

文章目录目录引言一、核心技术维度对比表二、分语言核心语法深度解析2.1 Go语言&#xff1a;简洁高效的“并发王者”2.1.1 变量声明与类型系统&#xff08;零值初始化指针&#xff09;2.1.2 流程控制&#xff08;仅for循环switch无穿透&#xff09;2.1.3 错误处理&#xff08;e…

作者头像 李华
网站建设 2026/4/20 21:51:22

【AIGC】RealVideo:一种基于自回归扩散视频生成的实时流媒体对话系统

系统概览图RealVideo 系统工作流程概述系统工作流程始于角色初始化&#xff1a;用户提供参考图像和参考语音文件用于克隆&#xff0c;系统据此实例化角色。用户还可以设置系统提示&#xff0c;指定模型应扮演的角色。随后&#xff0c;RealVideo 通过文本输入与用户交互。用户消…

作者头像 李华