#include <iostream>
#include <deque>
using namespace std;
class Guest {
public:
string name;
bool vip;
Guest(string name, bool vip) {
this->name = name;
this->vip = vip;
}
};
int main() {
Guest guest1("张三", false);
Guest guest2("李四", false);
Guest vipGuest("王五", true);
deque<Guest> deque = {vipGuest,guest1,guest2};
// write your code here......
for (Guest g : deque) {
cout << g.name << " ";
}
return 0;
}
C++ deque 容器 超详细使用教程(零基础易懂,和vector对比学,无缝上手)
你已经熟练掌握了vector和set,学deque会极致轻松!因为 deque 是 vector的「亲兄弟」,语法、函数、遍历方式99%和vector完全一致,只是比vector多了一个核心特性:支持【头部+尾部】高效增删元素,完美弥补了vector「头部增删效率极低」的缺点。
✅ 先给你一句定心丸:你会用vector,就等于已经会用99%的deque,只需要多记2个函数,全程和vector对比讲解,零记忆负担!
✅ 一、先搞懂:deque 是什么?【核心定义+和vector的区别(重中之重,必记)】
1. deque 核心含义
deque 是 double-ended queue 的缩写,翻译为「双端队列」,是STL中非常常用的容器,和vector同属于「序列式容器」。✅ deque 的 3个核心特性(灵魂,记住这3点就彻底懂了):① 支持下标随机访问 → d[i] 写法和vector完全一样,能直接通过下标读写元素;② 两端高效增删 → 头部(push_front)、尾部(push_back)插入/删除元素,效率都极高,O(1)时间复杂度;③ 允许重复元素 + 无序存储 → 插入顺序 = 存储顺序,不会自动排序、不会自动去重(和vector一致,和set相反)。
2. deque VS vector 核心对比(最关键,表格一目了然,你最需要的)
这是本次学习的核心重点,二者语法完全相通,特性互补,99%的函数名字都一样,这个表格记死,永远不会用错容器!
核心优势 | 尾部增删快(
),随机访问快 | ✅ 头部+尾部增删都超快 ,随机访问快 |
核心劣势 | 头部增删极慢(数据会整体后移) | 中间增删慢(和vector一样) |
下标访问 | 支持
随机访问 | ✅ 支持
随机访问,写法完全一样 |
元素特性 | 允许重复、无序存储 | ✅ 允许重复、无序存储(和vector一致) |
自动扩容 | 自动扩容,扩容效率一般 | 自动扩容,扩容效率更高(分段内存,无需拷贝) |
遍历方式 | 下标/迭代器/范围for | ✅ 完全相同的3种遍历方式 |
常用函数 | push_back/pop_back/size/empty等 | ✅ 包含vector所有函数 + 新增
|
✅ 一句话总结:什么时候用 deque?什么时候用 vector?
🔸 如果你只需要 尾部增删元素(比如:输入数据存入容器)→ 用
vector就行,足够用;🔸 如果你需要 头部也增删元素(比如:队列、滑动窗口、头尾都要操作)→ 无脑用deque;🔸 其他所有场景(下标访问、遍历、清空、判空),二者完全通用,随便选!
✅ 二、deque 前置必备(和vector完全一样,直接复用,无任何新内容)
1. 必加头文件
所有deque代码,必须引入这个专属头文件,仅此一个:
#include <deque> // deque的头文件,必须加 #include <iostream> using namespace std;
2. 命名空间
和vector/set一样,加using namespace std; 后直接写deque,不加则写std::deque,推荐加上,代码更简洁。
✅ 三、核心语法1:deque的「定义与初始化」(5种写法)
✅ 语法格式:deque<存储类型> 容器名;
和vector的定义语法 一字不差! 你写vector怎么定义,deque就怎么定义,<>里可以写int/char/string/自定义类,支持的类型和vector完全一致。
#include <iostream>
#include <deque>
using namespace std;
int main() {
// 写法1:定义空deque,最常用!先创建空队列,后续添加元素
deque<int> d1;
// 写法2:定义时直接初始化赋值(推荐,已知初始数据)
deque<int> d2 = {1, 2, 3, 4, 5};
// 写法3:指定长度,所有元素赋默认值0
deque<int> d3(5); // d3 = {0,0,0,0,0}
// 写法4:指定长度 + 指定初始化值
deque<int> d4(5, 10); // d4 = {10,10,10,10,10}
// 写法5:用一个deque初始化另一个deque(拷贝)
deque<int> d5(d2); // d5 = {1,2,3,4,5}
return 0;
}
✨ 补充:以上5种写法,把deque换成vector,代码完全不变,能正常运行,这就是语法相通的魅力!
✅ 四、核心语法2:deque 最常用的「增删改查」操作(重中之重)
✅ 核心结论:deque 包含了 vector 的全部成员函数 + 新增2个头部操作函数
你在vector学过的所有函数(push_back、size、empty、clear、[]等),在deque里完全能用,函数名、用法、返回值都一模一样!唯一的新增内容,就是 deque 的 灵魂2个函数,也是你唯一需要额外记忆的内容:
✅
push_front(值):向deque的头部插入一个元素✅pop_front():删除deque的头部第一个元素
✔️ 分模块讲解:所有操作(按优先级排序,越靠前越常用,共9个,够用100%场景)
所有例子都基于:deque<int> d = {1,2,3,4,5};,所有操作你都能在vector里找到对应版本
✅ 【增】元素插入 (3个函数,2个继承vector,1个新增)
- 尾部插入 【继承vector】
push_back(值)→ 和vector完全一样,向最后面加元素 - 头部插入 【新增核心】
push_front(值)→ deque的王牌功能,向最前面加元素,效率极高 - 中间插入 【继承vector】
insert(迭代器, 值)→ 和vector一样,在指定位置插入元素,中间增删效率一般,很少用
✅ 【删】元素删除 (3个函数,2个继承vector,1个新增)
- 尾部删除 【继承vector】
pop_back()→ 和vector完全一样,删除最后一个元素 - 头部删除 【新增核心】
pop_front()→ deque的王牌功能,删除第一个元素,效率极高 - 清空所有元素 【继承vector】
clear()→ 和vector完全一样,清空后size=0,容器为空
✅ 【改/查】核心操作 (3个函数,完全继承vector,无任何变化)
这部分零新内容,你闭着眼睛写就行,和vector的用法丝毫不差!
- 下标访问元素
d[下标]→ 最常用!支持读、写两种操作,下标从0开始,和数组/vector完全一致 - 获取容器长度
size()→ 返回元素个数,遍历必用,和vector完全一样 - 判断是否为空
empty()→ 为空返回true,不为空返回false,防止访问空容器崩溃,和vector完全一样
✅ 五、核心语法3:deque 的「遍历方式」(3种)
✅ 核心结论:和vector的遍历方式 完全一模一样!没有任何区别!
deque支持数组式遍历、迭代器遍历、范围for遍历,3种方式的语法、写法、效率,和vector完全相同,你之前写的vector遍历代码,把vector换成deque就能直接运行,这是你最爽的地方,零成本上手!
所有遍历例子都基于:
deque<int> d = {1,2,3,4,5};
✔️ 方式1:数组式遍历 【最推荐、最常用】 for(int i=0; i<d.size(); i++)
和数组、vector的遍历写法完全相同,语法最熟悉、代码最简洁、效率最高,90%的场景用这个就够了,也是你最喜欢的写法!
for (int i = 0; i < d.size(); i++) {
cout << d[i] << " "; // 用d[i]访问元素,和vector/数组无区别
}
// 输出:1 2 3 4 5
✔️ 方式2:迭代器遍历 【STL标准写法】 deque<int>::iterator
deque的迭代器和vector的迭代器语法完全一致,迭代器=容器专属指针,*it取值、it++移动,规则不变:
deque<int>::iterator it;
for (it = d.begin(); it != d.end(); it++) {
cout << *it << " "; // *it 访问元素,和指针一样
}
// 输出:1 2 3 4 5
✔️ 方式3:范围for遍历 【C++11极简写法】 for(auto x : d)
一行代码搞定遍历,不用下标、不用迭代器,代码量最少,适合快速开发,和vector的写法完全相同:
for (auto x : d) {
cout << x << " ";
}
// 输出:1 2 3 4 5
✅ 六、deque 经典实战案例(2个高频场景,你一定会用到!)
结合你之前写的vector输入案例、倒序案例,给你2个deque的经典实战代码,都是笔试/面试/开发的高频需求,直接复制运行,贴合你的使用场景,看完就会用!
✅ 案例1:deque 核心功能演示 → 头部+尾部增删元素(最经典)
这个案例完美体现deque的核心价值:头尾都能高效操作,这是vector做不到的高效操作!
#include <iostream>
#include <deque>
using namespace std;
int main() {
deque<int> d;
// 尾部插入3个元素
d.push_back(10);
d.push_back(20);
d.push_back(30);
// 头部插入2个元素
d.push_front(0);
d.push_front(-10);
// 此时d = {-10, 0, 10, 20, 30}
cout << "增删前:";
for(int i=0; i<d.size(); i++) cout << d[i] << " ";
cout << endl;
// 头部删除1个元素
d.pop_front();
// 尾部删除1个元素
d.pop_back();
// 此时d = {0, 10, 20}
cout << "增删后:";
for(int i=0; i<d.size(); i++) cout << d[i] << " ";
return 0;
}
✅ 运行结果:
增删前:-10 0 10 20 30 增删后:0 10 20
✅ 案例2:输入若干整数存入deque → 正序+倒序输出(你的原题,无缝替换vector)
你之前用vector写的「输入数字→正序→倒序」代码,把vector换成deque,代码完全不变,功能完全一致,完美适配!
#include <iostream>
#include <deque>
using namespace std;
int main() {
deque<int> d;
int a;
// 循环输入整数,存入deque
while(cin >> a){
d.push_back(a);
}
// 正序输出(数组式遍历)
cout << "正序:";
for(int i=0; i<d.size(); i++) cout << d[i] << " ";
cout << endl;
// 判空,避免崩溃
if(d.empty()) return 0;
// 倒序输出
cout << "倒序:";
for(int i=d.size()-1; i>=0; i--) cout << d[i] << " ";
return 0;
}
✅ 结束输入:和vector一样,Windows按Ctrl+Z回车,Linux/Mac按Ctrl+D。
✅ 七、deque 易错点避坑指南(3个经典坑,全部是vector的坑,无新坑!)
deque的坑全部继承自vector,你已经在vector里踩过这些坑,现在只需要复用经验即可,没有任何新坑,太友好了!
❌ 坑1:下标越界访问
deque<int> d = {1,2,3};
cout << d[5] << endl; // ❌ 下标5超出范围,程序崩溃
✅ 避坑:访问下标时,确保 i < d.size() 即可。
❌ 坑2:对空deque执行头部/尾部删除
deque<int> d; d.pop_front(); // ❌ 空容器删除元素,程序崩溃 d.pop_back(); // ❌ 同理崩溃
✅ 避坑:删除元素前,先用d.empty()判断是否为空。
❌ 坑3:认为deque的中间增删效率高
d.insert(d.begin()+2, 100); // 中间插入,效率一般
✅ 避坑:deque只有头尾增删效率高,中间增删效率和vector一样慢,尽量避免。
✅ 八、deque 常用操作速查表(收藏备查,和vector几乎一样)
deque<int> d; // 定义空deque d.push_back(x); // 尾部插入元素x(继承vector) d.push_front(x); // 头部插入元素x(新增核心) d.pop_back(); // 尾部删除元素(继承vector) d.pop_front(); // 头部删除元素(新增核心) d[i]; // 访问下标i的元素(读/写) d.size(); // 获取元素个数 d.empty(); // 判断是否为空 d.clear(); // 清空所有元素 d.insert(it, x); // 迭代器位置插入x d.erase(it); // 删除迭代器位置的元素
✅ 九、终极选择:vector / set / deque 三者怎么选?(万能原则,无脑套用)
你现在已经掌握了C++ STL中最核心的3个容器,这三个容器能解决99%的开发需求,这里给你一个万能选择原则,满足任意一个条件就用对应容器,永远不会选错,收藏好!
✅ 用 vector (满足其一)
- 只需要尾部增删元素,不需要头部操作;
- 对容器的遍历效率、随机访问效率要求极高;
✅ 用 deque (满足其一)
- 需要头部+尾部都进行增删操作;
- 不确定是否需要头部操作,想兼顾头尾效率;
✅ 用 set (满足其一)
- 需要自动去重 + 自动升序排序;
- 需要频繁判断某个元素是否存在(查找效率极高);
✅ 总结(核心知识点,一句话记死,永不忘记)
- deque 是双端队列,是vector的亲兄弟,语法99%和vector一致,会vector就会deque;
- deque的核心优势:头部+尾部增删都高效,vector只有尾部增删高效;
- deque的核心新增函数:
push_front(值)头插、pop_front()头删,仅此2个需要记忆; - deque支持下标访问、允许重复元素、无序存储,和vector一致,和set相反;
- 选择原则:头尾操作选deque,尾部操作选vector,去重排序选set。
你已经吃透了vector和set,学deque就是临门一脚,这个容器非常实用,尤其是在处理「队列」类的需求时,堪称神器!恭喜你又掌握了一个超实用的STL容器,你的C++工具箱越来越丰富啦!🎉
for (Guest g : dq)
✅ 这个语法的全称:【C++11 范围 for 循环 / 增强 for 循环】
这个语法是 C++11 标准新增的,专门用来简化「容器遍历」的写法,你之前学过 deque 的两种遍历方式:
- 数组式遍历
for(int i=0; i<dq.size(); i++) - 迭代器遍历
deque<Guest>::iterator it; for(it=dq.begin();...)
而 for (Guest g : dq) 是第三种遍历方式,也是最简单的一种,没有下标、没有迭代器,一行写完遍历,专门适配「从头到尾遍历整个容器」的需求。
✅ 逐字解析 for (Guest g : dq) 【重中之重,拆到你完全懂】
我们把这句代码切成 3 个部分,每一个部分你都学过,没有新知识!
cpp
运行
for ( Guest g : dq )
① 类型 ②变量名 ③固定符号 ④要遍历的容器
① Guest → 要遍历的容器里元素的类型
你的deque<Guest> dq 容器里,存的是一个个Guest类的对象 → 所以这里写Guest;
如果是deque<int> dq 存整数,这里就写int;
如果是vector<string> v 存字符串,这里就写string;
✅ 规则:
:左边的类型,必须和容器里存储的类型完全一致!
② g → 给遍历到的当前元素起的「临时名字」
这个g就像你写 int a 的a、vector<int>::iterator it的it一样,只是个变量名,你可以随便改:
比如写成for (Guest guest : dq)、for (Guest tmp : dq) 都可以,完全不影响功能;
遍历过程中,容器里的元素会从第一个到最后一个,依次赋值给这个临时变量 g。
③ : → 固定语法符号,没有实际含义,读作「在... 之中」
就像for、if一样是 C++ 关键字,必须写,不能改,记住就行。
④ dq → 你要遍历的容器的名字
就是你定义的deque<Guest> dq这个容器,要遍历谁,这里就写谁的名字。
✅ 这句代码的【人话翻译】(最通俗易懂,记死这个翻译)
cpp
运行
for (Guest g : dq) { ... }
翻译为:
依次取出 容器 dq 里的每一个 Guest 对象,把这个对象赋值给临时变量 g,然后执行大括号里的代码,直到遍历完所有对象为止。
遍历顺序是:从容器的第一个元素 → 最后一个元素,和你用数组式遍历的顺序完全一致!
✅ 第三步:这个遍历的【本质】+【等价写法】(彻底消除你的疑惑)
✅ 本质:范围 for 循环 = 编译器帮你简化的「迭代器遍历」
你写的 for (Guest g : dq),编译器在编译时,会自动帮你转换成迭代器遍历,等价于下面这段你学过的代码:
cpp
运行
// 手动写的迭代器遍历(你学过) ←→ 编译器自动转的,和范围for完全等价
deque<Guest>::iterator it;
for(it = dq.begin(); it != dq.end(); it++){
Guest g = *it; // 把迭代器指向的对象,赋值给临时变量g
cout << g.name << " ";
}

京公网安备 11010502036488号