当前位置: 首页 > news >正文

【C++学习】deque容器

一、deque 的核心特性

deque 是 STL 中 “全能型” 容器,核心价值是兼顾双端高效操作和随机访问,尤其适合需要频繁在首尾增删元素,同时又需通过索引访问的场景。实际开发中,若不确定用 vector 还是 list,且有双端操作需求,deque 是优先选择。

双端高效操作

首尾插入(push_front/push_back)、首尾删除(pop_front/pop_back)的时间复杂度均为 O(1),这是它区别于 vector(仅尾端高效)和 list(随机访问低效)的核心优势;

随机访问支持

可通过索引([]/at())访问元素,时间复杂度 O(1),但效率略低于 vector(底层结构更复杂);

动态扩容

无需提前固定大小,扩容时不移动全部元素(与 vector 不同),内存利用率更高;

底层结构

并非完全连续内存,而是由「多个连续内存块 + 中控数组」组成 —— 中控数组存储各内存块的地址,元素访问时先通过中控数组定位内存块,再访问块内元素,兼顾了双端操作和随机访问效率;
模板实现:支持存储任意类型(int、string、自定义类等),定义时需指定元素类型(如 deque)。

二、deque 的常用操作

1. 初始化(5 种常见方式)

#include <deque>
#include <iostream>
using namespace std;int main() {// 1. 空deque(默认初始化)deque<int> d1;// 2. 初始化n个默认值元素(int默认0,string默认空串)deque<int> d2(5);         // 5个0:[0,0,0,0,0]deque<string> d3(3);      // 3个空串:["","",""]// 3. 初始化n个指定值元素deque<int> d4(4, 10);     // 4个10:[10,10,10,10]// 4. 用初始化列表赋值(C++11+)deque<int> d5 = {1, 2, 3, 4};  // [1,2,3,4]deque<int> d6{5, 6, 7};        // 等价于d5的写法// 5. 拷贝其他deque(深拷贝)deque<int> d7(d5);        // 拷贝d5:[1,2,3,4]deque<int> d8 = d6;       // 拷贝d6:[5,6,7]return 0;
}

2.元素访问(4 种方式,与 vector 类似)

int main() {deque<int> d = {10, 20, 30, 40};// 1. 索引访问([]):无越界检查,越界会崩溃cout << d[0] << endl;  // 10cout << d[2] << endl;  // 30// 2. at() 访问:有越界检查,越界抛异常(更安全)cout << d.at(1) << endl;  // 20// d.at(10);  // 抛出 out_of_range 异常// 3. 访问首尾元素(核心优势,高效)cout << d.front() << endl;  // 首元素:10cout << d.back() << endl;   // 尾元素:40// 4. 迭代器/范围for遍历for (deque<int>::iterator it = d.begin(); it != d.end(); ++it) {cout << *it << " ";  // 10 20 30 40}for (int x : d) {cout << x << " ";  // 10 20 30 40}return 0;
}

3. 元素修改(双端操作是核心)

int main() {deque<int> d;// 1. 双端插入(核心功能,O(1))d.push_back(10);   // 尾插:[10]d.push_back(20);   // 尾插:[10,20]d.push_front(5);   // 首插:[5,10,20]d.push_front(1);   // 首插:[1,5,10,20]// 2. 双端删除(核心功能,O(1))d.pop_back();      // 尾删:[1,5,10]d.pop_front();     // 首删:[5,10]// 3. 中间插入/删除(效率低于 list,O(n))// 在索引1处插入3(迭代器定位)d.insert(d.begin() + 1, 3);  // [5,3,10]// 删除索引0的元素d.erase(d.begin());          // [3,10]// 4. 清空元素(clear):size变为0,容量可能保留d.clear();        // 空dequereturn 0;
}

4. 容量与大小操作

int main() {deque<int> d(4, 10);  // 初始:size=4// 1. 获取当前元素个数(size)cout << "size: " << d.size() << endl;  // 4// 2. 检查是否为空(empty)cout << "empty: " << (d.empty() ? "是" : "否") << endl;  // 否// 3. 调整大小(resize):新增元素补默认值/指定值d.resize(6);    // size=6,新增2个0:[10,10,10,10,0,0]d.resize(8, 5); // size=8,新增2个5:[10,10,10,10,0,0,5,5]// 4. 预留容量(reserve):deque的reserve仅保证容量不小于n,不收缩容量d.reserve(10);  // 容量至少为10,size仍为8return 0;
}

三、deque 的常见使用场景

双端队列需求

如实现 “滑动窗口” 算法(需从首尾删除元素)、缓存队列(需从队首取元素,队尾加元素);

作为容器适配器的底层

STL 中的 stack(栈)和 queue(队列)默认用 deque 作为底层容器(因双端操作高效,且支持随机访问);

替代 vector 的首插场景

若需频繁在头部插入元素,deque 的 push_front(O (1))远优于 vector 的首插(O (n))。

四、注意事项

迭代器失效问题

deque 的首尾插入 / 删除可能导致迭代器失效(若触发内存块增减),中间插入 / 删除会导致插入点后的迭代器失效;
避免在迭代器访问期间修改 deque 大小(如 push_back/pop_front),若修改需重新获取迭代器。

内存碎片

虽 deque 扩容不移动全部元素,但多个内存块可能导致一定内存碎片,若对内存连续性要求极高(如直接访问内存地址),需用 vector。

自定义类存储

与 vector 类似,存储自定义类时需确保有默认构造函数,若包含动态内存,需实现深拷贝(避免内存泄漏)。

http://www.dtcms.com/a/574019.html

相关文章:

  • 网站程序代码更加精准高效的措施
  • 宁波网站建设h5哪个做网站平台好
  • Apache IoTDB 技术深度解析:存储引擎、查询优化与分布式架构在工业物联网、智慧能源和车联网场景的应用指南
  • rap2部署
  • IOT-VIP——STM32F031K6U6+RS485+显示屏
  • 工业互联网 “云 - 边 - 端” 架构
  • c#网站开发框架深圳网站建设收费
  • MAC电脑上拉取Git仓库的方法
  • 怎样在网做旅游网站顺企网浙江网站建设
  • 时序数据库系列(四):InfluxQL查询语言详解
  • 如何建设专业化的网站全球搜索网站排名
  • Android WebView - loadUrl 方法的长度限制
  • 温州网站推广公司wordpress万能
  • 开题报告之基于SpringBoot框架的在线答题网站的设计与实现
  • 珠海建站专业做辅助的网站
  • 南山做网站海外购物app排行榜前十名
  • 从一题了解 CROSS JOIN 与 DATEDIFF:SQL 天气温度对比实战
  • js:requestAnimationFrame的使用
  • 【JUnit实战3_29】第十八章:REST API 接口测试(上)——RESTful 风格的后端 API 的搭建
  • 回调函数的作用与举例(Python版)
  • 克旗网站制作5229998建设银行网站会员
  • 洛阳市政建设网站网站建设中 html免费
  • 自己创建网站怎么赚钱青海省住房建设厅网站首页
  • MiniEngine学习笔记 : DescriptorHeap
  • 智能合约与智能合约开发交互详解
  • 我想出租做房 请问哪个网站好些泰安最新通告今天
  • 下一代CDN安全体系:融合加速、抗攻击与业务智能
  • 光纤传输器与网络延长器2合1技术解析:
  • OpenHarmony开发实践-鸿蒙napi开发实践
  • Redis识别缓存与数据库数据的不一致性以及识别热Key教程