C++ STL deque(双端队列)学习笔记:容器界的 “全能选手”
前言
如果说 vector 是 “只能从尾巴增删的倔脾气选手”,queue 是 “只能前门出、后门进的规矩人”,那 deque(双端队列)就是容器界的 六边形战士—— 既能像 vector 一样随机访问,又能像 queue 一样操作两端,甚至还能在中间插删(虽然效率不如 list,但胜在灵活)。今天就结合我的练习代码,用唠嗑的方式聊聊这个 “全能选手” 怎么用~
1. deque 基础:构造方法(原 test08)
功能说明
跟所有容器一样,deque 也有 “开卡方式”,不同构造方法对应不同场景,比如 “空卡”“预制卡”“复制卡”,咱们一个个看。
代码实现(改名 + 爆笑注释)
cpp
运行
#include <string>
#include <iostream>
#include <math.h>
#include <ctime>
#include <queue>
#include <deque> // 用deque必须加这个头文件,别忘!
using namespace std;
// -------------------------- deque的构造方法:花式开卡指南 --------------------------
// 功能:演示deque的5种构造方式,像开不同类型的游戏卡一样简单
void deque_construction_methods() {
// 1. 默认构造:开一张“空卡”,啥都没有,后续自己加内容
deque<int> dq_empty;
// 2. 指定大小构造:开一张“预制空卡”,有10个位置,但每个位置都是默认值(int默认0)
deque<int> dq_size_only(10);
// 3. 大小+默认值构造:开一张“预制满卡”,10个位置,每个位置都写1(相当于批量填值)
deque<int> dq_size_with_val(10, 1);
// 4. 拷贝构造:复制别人的卡!把dq_size_with_val的所有内容抄到dq_copy里
deque<int> dq_copy(dq_size_with_val);
// 5. 迭代器范围构造:“精准抄卡”,只抄dq_size_with_val的前3个元素(左闭右开,[begin, begin+3))
// 相当于从大卡上剪一小块下来,做成新卡
deque<int> dq_range(dq_size_with_val.begin(), dq_size_with_val.begin() + 3);
// 打印dq_range,看看抄对没(应该是1 1 1)
cout << "迭代器构造的deque内容:";
for (auto it = dq_range.begin(); it != dq_range.end(); it++) {
cout << *it << " ";
}
cout << endl; // 输出:1 1 1
}
构造方法总结(人话版)
| 构造方式 | 人话解释 | 适用场景 |
|---|---|---|
deque<T> dq; | 空卡,啥都没有 | 不确定初始内容,后续动态加 |
deque<T> dq(n); | n 个位置的空卡,默认值填充 | 知道需要多少位置,值后续填 |
deque<T> dq(n, val); | n 个位置的满卡,全填 val | 批量初始化相同值(如全 0、全 1) |
deque<T> dq(other); | 复制别人的卡 | 需要一个一模一样的副本 |
deque<T> dq(beg, end); | 剪别人卡的一部分做新卡 | 只需要其他容器的部分内容 |
2. deque 核心:插入操作(原 test09)
功能说明
deque 最牛的点之一就是 “两端都能插,中间也能插”—— 前门(队头)、后门(队尾)随便进,甚至能在中间 “插队”(虽然插队效率一般,但偶尔能用)。
代码实现(改名 + 爆笑注释)
cpp
运行
// -------------------------- deque的插入操作:前门、后门、中间随便进 --------------------------
// 功能:演示deque的3种插入方式:两端push、中间insert
void deque_insert_operations() {
// 先开一张空卡
deque<int> dq;
// 1. 后门插入(push_back):最常用,像排队从后门悄悄加塞(不对,是正常排队)
dq.push_back(4); // 卡内:[4]
dq.push_back(5); // 卡内:[4, 5](后门进,5排最后)
// 2. 中间插入(insert):找个迭代器位置“插队”,这里选队头(begin())
deque<int>::iterator it = dq.begin(); // 定位到队头(4的位置)
dq.insert(it, 2); // 在队头插2,卡内:[2, 4, 5](2插在最前面)
// 3. 中间批量插入:在队头插3个9,相当于“一群人插队”
dq.insert(dq.begin(), 3, 9); // 卡内:[9, 9, 9, 2, 4, 5]
// 4. 用其他容器的范围插入:从dq2里剪一块插进来
deque<int> dq2 = {11, 22}; // 另一张卡
// 只插dq2的最后1个元素(22):dq2.end()-1是22的位置,dq2.end()是尾后,左闭右开
dq.insert(dq.begin(), dq2.end() - 1, dq2.end()); // 卡内:[22, 9, 9, 9, 2, 4, 5]
// 正向遍历:看看最终队伍
cout << "正向遍历(从队头到队尾):";
for (auto it = dq.begin(); it != dq.end(); it++) {
cout << *it << " ";
}
cout << endl; // 输出:22 9 9 9 2 4 5
// 反向遍历:从队尾往队头看(像从后往前数队伍)
cout << "反向遍历(从队尾到队头):";
for (auto it = dq.rbegin(); it != dq.rend(); it++) {
cout << *it << " ";
}
cout << endl; // 输出:5 4 2 9 9 9 22
}
插入操作总结(人话版)
| 插入方式 | 人话解释 | 效率 |
|---|---|---|
dq.push_front(val) | 前门进,插在队头 | 快(deque 强项,比 vector 头插快多了) |
dq.push_back(val) | 后门进,插在队尾 | 快(跟 vector 尾插差不多) |
dq.insert(it, val) | 在迭代器 it 位置插单个 val(插队) | 慢(中间元素要移动,元素多了更慢) |
dq.insert(it, n, val) | 在 it 位置插 n 个 val(批量插队) | 慢(同上,移动元素更多) |
dq.insert(it, beg, end) | 在 it 位置插其他容器的 [beg,end) 范围 | 慢(看插入长度,越长越慢) |
3. deque 核心:删除操作(原 test10)
功能说明
有插就有删,deque 删元素也很灵活:前门删、后门删、中间删,甚至能清空整个队伍。但记住:中间删还是慢,尽量少用~
代码实现(改名 + 爆笑注释)
cpp
运行
// -------------------------- deque的删除操作:前门、后门、中间随便删 --------------------------
// 功能:演示deque的4种删除方式:两端pop、中间erase、清空clear
void deque_delete_operations() {
// 先开一张卡,用循环从后门加10个元素(0-9)
deque<int> dq;
for (int i = 0; i < 10; i++) {
dq.push_back(i); // 卡内:[0,1,2,3,4,5,6,7,8,9]
}
// 1. 前门删除(pop_front):队头第一个元素滚蛋(0再见)
dq.pop_front(); // 卡内:[1,2,3,4,5,6,7,8,9]
// 2. 后门删除(pop_back):队尾最后一个元素滚蛋(9再见)
dq.pop_back(); // 卡内:[1,2,3,4,5,6,7,8]
// 3. 中间删除单个元素:定位到队头(1),删了它
deque<int>::iterator it = dq.begin();
dq.erase(it); // 卡内:[2,3,4,5,6,7,8]
// 4. 中间删除范围:删队头开始的2个元素(2和3再见)
dq.erase(dq.begin(), dq.begin() + 2); // 卡内:[4,5,6,7,8]
// 遍历看看剩下的元素
cout << "删除后剩下的元素:";
for (auto it = dq.begin(); it != dq.end(); it++) {
cout << *it << " ";
}
cout << endl; // 输出:4 5 6 7 8
// 5. 清空整个deque:一键清空,啥都不剩
dq.clear();
cout << "清空后元素个数(size):" << dq.size() << endl; // 输出:0
cout << "清空后是否为空(empty):" << dq.empty() << endl; // 输出:1(true)
}
删除操作总结(避坑提醒)
pop_front()/pop_back():只能删两端,无返回值(想知道删了啥,先front()/back()看一眼);erase(it)/erase(beg, end):删中间元素,返回下一个元素的迭代器(但咱不用记,知道能删就行);clear():清空所有元素,但不释放内存(容量capacity不变,下次用还能接着装);- 避坑:别删空 deque!
pop_front()/pop_back()/erase()在空 deque 上调用会崩溃,删之前最好用empty()判断一下~
4. deque 访问:随机访问 + 安全访问(原 test11)
功能说明
deque 比 queue 牛的地方在于:它能像 vector 一样用下标访问任意元素,还支持at()安全访问(越界会报错,不像[]直接崩溃)。
代码实现(改名 + 爆笑注释)
cpp
// -------------------------- deque的元素访问:下标浪着来,at带着保镖 --------------------------
// 功能:演示deque的4种访问方式:下标[]、at()、front()、back()
void deque_access_operations() {
// 先开一张有内容的卡:[1,2,3,4,5,6]
deque<int> dq = {1,2,3,4,5,6};
// 1. 下标访问([]):跟vector一样浪,直接按位置取(下标从0开始)
cout << "下标2的元素([]访问):" << dq[2] << endl; // 输出:3(第3个元素)
// 循环用下标遍历,像vector一样方便
cout << "下标遍历所有元素:";
for (int i = 0; i < dq.size(); i++) {
cout << dq[i] << " ";
}
cout << endl; // 输出:1 2 3 4 5 6
// 2. at()访问:带保镖的访问!越界会抛异常,不会直接崩溃
cout << "at(3)的元素(安全访问):" << dq.at(3) << endl; // 输出:4
// 故意访问不存在的下标(40),看看保镖怎么干活
try {
cout << dq.at(40) << endl; // 下标40不存在,抛异常
} catch (exception e) {
// 捕获异常,打印错误信息(比直接崩溃友好多了)
cout << "访问越界啦!错误信息:" << e.what() << endl; // 输出类似"out of range"
}
// 3. 访问队头(front()):直接取第一个元素,不用记下标0
cout << "队头元素(front()):" << dq.front() << endl; // 输出:1
// 4. 访问队尾(back()):直接取最后一个元素,不用记size-1
cout << "队尾元素(back()):" << dq.back() << endl; // 输出:6
}
访问方式对比(选对方式不踩坑)
| 访问方式 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
dq[i] | 快,写起来方便 | 越界直接崩溃,不安全 | 确定下标合法时(比如循环内) |
dq.at(i) | 越界抛异常,安全 | 比 [] 慢一丢丢(忽略不计) | 不确定下标是否合法时 |
dq.front() | 直接取队头,不用记下标 0 | 只能取队头 | 要第一个元素时 |
dq.back() | 直接取队尾,不用记 size-1 | 只能取队尾 | 要最后一个元素时 |
5. deque 大小操作:调整队伍规模(原 test12)
功能说明
deque 能调整元素个数(resize),还能查大小(size)、最大容量(max_size)、是否为空(empty)—— 相当于 “队伍人数管理”。
代码实现(改名 + 爆笑注释)
cpp
// -------------------------- deque的大小操作:队伍人数我说了算 --------------------------
// 功能:演示deque的大小相关操作:size()、max_size()、resize()、empty()
void deque_size_operations() {
// 先开一张卡:[1,2,3,4,5]
deque<int> dq = {1,2,3,4,5};
// 1. 查当前元素个数(size()):看看队伍有多少人
cout << "当前队伍人数(size):" << dq.size() << endl; // 输出:5
// 2. 查最大容量(max_size()):理论上最多能装多少人(系统决定,不用太在意)
cout << "理论最大人数(max_size):" << dq.max_size() << endl; // 输出一个大数字(比如2e9)
// 3. 调整元素个数(resize(n)):强行把队伍人数改成n
dq.resize(0); // 改成0人,相当于清空(但比clear()灵活,能改任意大小)
cout << "调整后队伍人数(size):" << dq.size() << endl; // 输出:0
// 4. 判断是否为空(empty()):看看队伍是不是没人了
if (dq.empty()) {
cout << "队伍空啦!赶紧招人吧~" << endl; // 会执行这句
}
}
大小操作总结(人话版)
size():当前有多少元素(“现在队伍人数”);max_size():最多能装多少元素(“场地最大容量”,不用纠结具体值);resize(n):强行改元素个数 ——n 比当前小,删后面的;n 比当前大,补默认值(int 补 0,string 补空串);empty():判断是否为空(“队伍没人了吗”),比size() == 0更高效。
6. deque 赋值与交换:批量填值 + 换队伍(原 test13)
功能说明
deque 能批量赋值(assign)—— 相当于 “给队伍所有人换统一服装”,还能跟其他 deque 交换内容(swap)—— 相当于 “两队人互换场地”。
代码实现(改名 + 爆笑注释)
cpp
// -------------------------- deque的赋值与交换:批量换装+换队伍 --------------------------
// 功能:演示deque的assign()赋值和swap()交换操作
void deque_assign_swap() {
// 1. assign()批量赋值:给队伍统一“换装”
deque<int> dq1;
dq1.assign(3, 1); // 3个人,全穿1号衣服(元素全为1):[1,1,1]
deque<int> dq2;
dq2.assign(3, 2); // 3个人,全穿2号衣服(元素全为2):[2,2,2]
// 打印换装后的两队
cout << "dq1换装后:";
for (auto it = dq1.begin(); it != dq1.end(); it++) {
cout << *it << " ";
}
cout << endl; // 输出:1 1 1
cout << "dq2换装后:";
for (auto it = dq2.begin(); it != dq2.end(); it++) {
cout << *it << " ";
}
cout << endl; // 输出:2 2 2
// 2. swap()交换:两队人互换场地(dq1穿2号,dq2穿1号)
dq1.swap(dq2);
// 打印交换后的两队
cout << "swap后dq1:";
for (auto it = dq1.begin(); it != dq1.end(); it++) {
cout << *it << " ";
}
cout << endl; // 输出:2 2 2
cout << "swap后dq2:";
for (auto it = dq2.begin(); it != dq2.end(); it++) {
cout << *it << " ";
}
cout << endl; // 输出:1 1 1
}
赋值与交换总结(避坑)
assign(n, val):会覆盖原有内容!不管之前有多少元素,都会变成 n 个 val;swap(dq1, dq2):交换的是内容,不是容器本身!效率极高(只换指针,不拷贝元素);- 避坑:
assign和swap的两个 deque 必须是同类型(比如都是deque<int>),不能跨类型交换。
7. deque 实战:VIP 顾客排队(原 test14)
功能说明
这是最贴近生活的例子:VIP 顾客不用排队,直接从队头进;普通顾客老老实实从队尾进 ——deque 的push_front和push_back完美适配这个场景!
代码实现(改名 + 爆笑注释)
cpp
运行
// -------------------------- deque实战:VIP优先排队系统 --------------------------
// 功能:用deque模拟VIP顾客走前门,普通顾客走后门的排队场景
void deque_vip_queue_demo() {
// 先定义一个“顾客”类:有名字(name)和是否VIP(vip)
class Guest {
public:
string name; // 顾客名字
bool vip; // 是否VIP(true=VIP,false=普通)
// 构造函数:创建顾客时给名字和VIP身份
Guest(string name, bool vip) {
this->name = name;
this->vip = vip;
}
};
// 1. 初始化4个顾客:2个VIP,2个普通
Guest guest1("小鹏", false); // 普通顾客:小鹏
Guest guest2("小明", false); // 普通顾客:小明
Guest guest3("小华", true); // VIP顾客:小华
Guest guest4("小花", true); // VIP顾客:小花
// 2. 创建deque队列:管理排队的顾客
deque<Guest> guest_queue;
// 3. VIP顾客走前门(push_front):不用排队,直接插队头
guest_queue.push_front(guest3); // 小华先插
guest_queue.push_front(guest4); // 小花再插(小花在队头,小华在后面)
// 4. 普通顾客走后门(push_back):老老实实排队,排队尾
guest_queue.push_back(guest2); // 小明排最后
guest_queue.push_back(guest1); // 小鹏排小明后面
// 5. 打印排队顺序:看看VIP是不是在前面
cout << "最终排队顺序(VIP在前,普通在后):";
for (Guest g : guest_queue) {
cout << g.name << " ";
}
cout << endl; // 输出:小花 小华 小明 小鹏(VIP在前,没毛病)
}
实战总结(学以致用)
- deque 的
push_front(前门)+push_back(后门) 是核心,完美适配 “优先级排队” 场景; - 类似场景还有:消息队列(紧急消息走前门,普通消息走后门)、缓存队列(新数据走前门,旧数据走后门)等。
8. deque vs vector vs queue:该选谁?
很多人学完这三个容器会懵:到底啥时候用哪个?给你一张 “选择指南”,保准不迷路:
| 容器 | 核心优势 | 核心劣势 | 适用场景 |
|---|---|---|---|
| deque | 两端增删快、支持随机访问 | 中间增删慢 | 优先级排队、两端操作 + 偶尔随机访问 |
| vector | 随机访问快、尾增删快 | 头增删慢、中间增删慢 | 大量随机访问、尾增删(如数组) |
| queue | 严格 FIFO、操作简单 | 不能随机访问、只能两端删 | 普通排队(如任务调度) |
口诀:两端操作找 deque,随机访问找 vector,严格排队找 queue。
总结
deque 就像容器界的 “万金油”—— 虽然没有单项最强,但胜在全面:两端增删快、支持随机访问、操作灵活。记住这几个核心点,下次用到就能秒选:
- 构造用
deque<T> dq(n, val)批量初始化; - 增删优先用
push_front/push_back和pop_front/pop_back(快); - 访问用
[](快)或at()(安全); - 实战用 “前门 VIP,后门普通” 的排队逻辑。
C++ deque 常用操作速查表
(按 “构造→增删→访问→大小→赋值交换” 分类,附示例 + 避坑点,复习时直接查!)
一、构造方法(创建 deque 对象)
| 函数 / 语法 | 功能说明 | 示例代码 | 注意事项 |
|---|---|---|---|
deque<T> dq; | 默认构造:空 deque | deque<int> dq; | 初始无元素,后续用 push 添加 |
deque<T> dq(n); | 指定大小:n 个元素,默认值填充(int 为 0) | deque<int> dq(5); // [0,0,0,0,0] | 只定大小不定值,适合后续批量赋值 |
deque<T> dq(n, val); | 大小 + 值:n 个元素,全填 val | deque<int> dq(3, 6); // [6,6,6] | 批量初始化相同值,最常用之一 |
deque<T> dq(other); | 拷贝构造:复制另一个 deque 的所有元素 | deque<int> dq2(dq1); | 两 deque 类型必须一致(如都是 int) |
deque<T> dq(beg, end); | 范围构造:复制 [beg, end) 区间的元素 | deque<int> dq(dq1.begin(), dq1.begin()+2); | 左闭右开区间,适合取其他容器的部分元素 |
二、插入操作(添加元素)
| 函数名 | 功能说明 | 示例代码 | 效率 / 注意事项 |
|---|---|---|---|
dq.push_front(val) | 队头插入:在最前面加元素 val | dq.push_front(2); // [2]→[1,2](原 [1]) | 快(deque 强项),比 vector 头插高效 |
dq.push_back(val) | 队尾插入:在最后面加元素 val | dq.push_back(3); // [1,2]→[1,2,3] | 快(和 vector 尾插效率相当) |
dq.insert(it, val) | 迭代器位置插:在 it 处插单个 val | auto it = dq.begin(); dq.insert(it, 0); | 慢(需移动后续元素,元素多慎用) |
dq.insert(it, n, val) | 迭代器位置批量插:在 it 处插 n 个 val | dq.insert(it, 2, 9); // 插 2 个 9 | 慢(移动元素更多,尽量少用) |
dq.insert(it, beg, end) | 迭代器位置范围插:插 [beg, end) 区间元素 | dq.insert(it, dq2.begin(), dq2.end()); | 慢(看插入长度,越长越慢) |
三、删除操作(移除元素)
| 函数名 | 功能说明 | 示例代码 | 避坑点 |
|---|---|---|---|
dq.pop_front() | 队头删除:删最前面的元素 | dq.pop_front(); // [1,2,3]→[2,3] | ❌ 不能删空 deque!删前用 empty() 判断 |
dq.pop_back() | 队尾删除:删最后面的元素 | dq.pop_back(); // [2,3]→[2] | ❌ 不能删空 deque!同上 |
dq.erase(it) | 迭代器位置删:删 it 指向的元素 | auto it = dq.begin(); dq.erase(it); | ❌ it 不能是 end()(无效位置) |
dq.erase(beg, end) | 范围删除:删 [beg, end) 区间的元素 | dq.erase(dq.begin(), dq.begin()+2); | ❌ 区间不能越界(如 beg > end) |
dq.clear() | 清空所有元素:size 变为 0,容量不变 | dq.clear(); // [2,3,4]→空 | 不清空内存(capacity 保留),下次用可复用 |
四、访问操作(获取元素)
| 函数名 / 语法 | 功能说明 | 示例代码 | 优势 / 避坑点 |
|---|---|---|---|
dq[i] | 下标访问:直接取第 i 个元素(0 开始) | cout << dq[2]; // 取第 3 个元素 | ✅ 快;❌ 越界直接崩溃,不安全 |
dq.at(i) | 安全访问:取第 i 个元素,越界抛异常 | cout << dq.at(2); | ✅ 越界报错(好调试);❌ 比 [] 慢一点 |
dq.front() | 访问队头:取最前面的元素 | cout << dq.front(); | ✅ 不用记 0 下标;❌ 不能访问空 deque |
dq.back() | 访问队尾:取最后面的元素 | cout << dq.back(); | ✅ 不用记 size()-1;❌ 不能访问空 deque |
五、大小操作(管理元素个数)
| 函数名 | 功能说明 | 示例代码 | 用途 |
|---|---|---|---|
dq.size() | 返回当前元素个数(实际存储的元素) | int len = dq.size(); | 循环遍历(如 for(int i=0; i<dq.size(); i++)) |
dq.max_size() | 返回理论最大元素个数(系统决定) | cout << dq.max_size(); | 几乎不用(了解即可,一般用不到上限) |
dq.resize(n) | 调整元素个数为 n:n 小则删,n 大则补默认值 | dq.resize(5); // 不够补 0(int 类型) | 灵活调整规模(如缩容、扩容补默认值) |
dq.empty() | 判断是否为空(true = 空,false = 非空) | if (dq.empty()) { ... } | 删元素 / 访问前必用(避免崩溃) |
六、赋值与交换(批量赋值 / 交换内容)
| 函数名 | 功能说明 | 示例代码 | 注意事项 |
|---|---|---|---|
dq.assign(n, val) | 批量赋值:覆盖原有元素,变为 n 个 val | dq.assign(3, 8); // 不管之前有啥,变成 [8,8,8] | 会清空原有内容,谨慎用(覆盖不可逆) |
dq.assign(beg, end) | 范围赋值:覆盖原有元素,变为 [beg, end) 区间元素 | dq.assign(dq2.begin(), dq2.end()); | 两容器类型需兼容(如都是 int 容器) |
dq1.swap(dq2) | 交换内容:dq1 和 dq2 的元素互换 | dq1.swap(dq2); | ✅ 效率极高(只换指针,不拷贝元素);❌ 类型必须一致 |
七、实战场景对应操作(快速联想)
| 实战场景 | 用到的核心操作 | 示例(如 VIP 排队) |
|---|---|---|
| VIP 优先排队(前门进) | push_front()(VIP)+ push_back()(普通) | dq.push_front(vip_guest); dq.push_back(normal_guest); |
| 消息队列(紧急消息优先) | push_front()(紧急)+ push_back()(普通) | dq.push_front(urgent_msg); dq.push_back(normal_msg); |
| 批量初始化相同值 | deque(n, val) 或 assign(n, val) | deque<int> dq(5, 10); // 5 个 10 |
| 安全遍历元素 | at(i) 或 front()/back() + empty() 判断 | if (!dq.empty()) cout << dq.at(0); |
最后附上我自己练习时的源码资料(有兴趣的可以按自己喜好自由练习修改):
头文件:
#pragma once
#include <string>
#include <iostream>
#include <math.h>
#include <ctime>
#include <queue> //使用队列容器需要的头文件
using namespace std;
/*
声明函数方法
*/
void test08();
void test09();
void test10();
void test11();
void test12();
void test13();
void test14();
源文件:
#include "deque双端队列容器.h"
/*
双端队列=》变异的vector向量
*/
/*
函数方法定义实现
*/
class Guest {
public:
string name;
bool vip;
public:
Guest(string name, bool vip) {
this->name = name;
this->vip = vip;
}
};
void test14() {
//初始化顾客
Guest g1("小鹏", false);
Guest g2("小明", false);
Guest g3("小华", true);
Guest g4("小花", true);
//创建队列
deque<Guest> dq;
//vip顾客使用头插法
dq.push_front(g3);
dq.push_front(g4);
//普通顾客使用尾插法,从队尾插入,老老实实排队吧
dq.push_back(g2);
dq.push_back(g1);
for (Guest g : dq) {
cout << g.name << " ";
}
//for (auto i = dq.begin(); i != dq.end(); i++) {
// cout << i->name << " ";
//}
}
void test13() {
deque<int> d1;
d1.assign(3, 1);//前三个元素赋值为1
deque<int> d2;
d2.assign(3, 2);
for (auto i = d1.begin(); i != d1.end(); i++) {
cout << *i <<" ";
}
cout << endl;
for (auto i = d2.begin(); i != d2.end(); i++) {
cout << *i << " ";
}
cout << endl;
d1.swap(d2);
for (auto i = d1.begin(); i != d1.end(); i++) {
cout << *i << " ";
}
cout << endl;
for (auto i = d2.begin(); i != d2.end(); i++) {
cout << *i << " ";
}
cout << endl;
}
void test12() {
deque<int> d1 = { 1,2,3,4,5 };
//元素个数
cout << d1.size() << endl;
cout << d1.max_size() << endl;
d1.resize(0);//更改双端队列的元素个数容量
cout << d1.size() << endl;
if (d1.empty()) {
cout << "没有元素了" << endl;
}
}
void test11() {
deque<int> d1 = { 1,2,3,4,5,6 };
//通过下标访问
cout << d1[2] << endl;
for (int i = 0; i < d1.size(); i++) {
cout << d1[i] << " ";
}
cout << endl;
try {
//通过at函数访问
cout << d1.at(40) << endl;
}
catch (exception e) {
cout << e.what() << endl;
}
//访问队头元素
cout << d1.front() << endl;
//访问队尾元素
cout << d1.back() << endl;
}
void test10() {
deque<int> d1;
//循环赋值
for (int i = 0; i < 10; i++) {
d1.push_back(i);
}
//头部出队
d1.pop_front();//删除0
//尾部出队
d1.pop_back();//删除9
deque<int>::iterator it = d1.begin();
d1.erase(it);//删除1
d1.erase(d1.begin(), d1.begin() + 2);//删除2 3
//遍历迭代器
for (auto i = d1.begin(); i != d1.end(); i++) {
cout << *i << " ";
}
cout << endl;
//cout << d1.at(100) << endl; bug代码
//清空双端队列
d1.clear();
cout << "d1.size():" << d1.size() << endl;
cout << "d1.empty():" << d1.empty() << endl;
}
void test09() {
deque<int> d1;
//队头添加元素
d1.push_back(4);
//队尾添加元素
d1.push_back(5);
deque<int>::iterator it = d1.begin();
d1.insert(it, 2); //在d1.begin()的位置插入2
d1.insert(d1.begin(), 3, 9); //在begin()的位置插入3个9
deque<int> d2 = { 11,22 };
//在d1.begin()的位置插入d2的队尾元素
d1.insert(d1.begin(), d2.end() - 1, d2.end());
//迭代输出d1的所有元素 22 9 9 9 2 4 5
for (auto i = d1.begin(); i != d1.end(); i++) {
cout << *i << " ";
}
cout << endl;
//反向迭代输出d1的所有元素 22 9 9 9 2 4 5
for (auto i = d1.rbegin(); i != d1.rend(); i++) {
cout << *i << " ";
}
cout << endl;
}
void test08() {
deque<int> d1; //默认构造函数
deque<int> d2(10); //定义一个int类型的双端队列,并且初始化大小为10
deque<int> d3(10, 1); //长度为10,每个元素值为1
deque<int> d4(d3); //使用d3来初始化d4双端队列
//[ d3.begin() , d3.begin()+3 ),左闭右开区间
deque<int> d5(d3.begin(), d3.begin() + 3); //使用迭代器初始化
for (auto i = d5.begin(); i != d5.end(); i++) {
cout << *i << " ";
}
cout << endl;
}
更多推荐



所有评论(0)