deque容器
deque(double-ended queue 双端队列),支持两端高效插入和删除,并且支持和vector一样的随机访问。 底层结构:deque底层并不是一块连续的内存,而是由多块固定大小的连续内存和一个指向这些块的中控数组组成的。这种结构既保证了随机访问的效率(通过中控数组定位块,再偏移访问元素),又支持两端快速扩容 / 缩容。 优势:
- 头部 / 尾部插入 / 删除:时间复杂度O(1)(远优于 vector 的头部操作O(n));
- 随机访问:时间复杂度O(1)(和 vector 一致,优于 list 的 O(n));
- 扩容成本低:无需像 vector 那样整体拷贝,只需新增内存块并更新中控数组。 劣势:
- 内存开销略高(中控数组 + 多个内存块的额外管理);
- 迭代器比 vector 复杂(需记录当前块和块内偏移)。
基本使用
- 使用 deque 需包含头文件<deque>;
#include <deque>
- 初始化方法(构造方法)
// 1、空初始化,默认构造函数
deque<int> d1;
// 2、初始化指定数量和初始化值
deque<int> d2(10, 6);
// 3、拷贝构造函数
deque<int> d3(d2);
// 4、迭代器范围初始化
int arr[] = { 0, 1, 2, 3, 4 , 5 };
deque<int> d4(arr, arr + 5);
// 5、列表初始化(c++ 11)
deque<int> d5 = { 0, 1, 2, 3, 4, 5 };
核心操作API
元素访问
[]:随机访问(无越界检查,速度快);at():随机访问(有越界检查,更安全);front():获取第一个元素;back():获取最后一个元素。
deque<int> d = { 0, 1, 2, 3, 4, 5 };
// [] 随机访问,没有越界检查
cout << d[5] << endl;
// at()随机访问,有越界检查抛出异常
cout << d.at(2) << endl;
// 首尾元素
cout << d.front() << " " << d.back() << endl;
插入与删除
- push_front(val),头部插入元素
- push_back(val),尾部插入元素
- pop_front(),删除头部元素
- pop_back(),删除尾部元素
- insert(pos, val),在迭代器pos位置插入元素
- erase(pos),删除迭代器pos位置的元素
- clear(),清除所有元素
deque<int> d = { 0, 1, 2, 3, 4, 5 };
// 头尾添加
d.push_front(100);
d.push_back(500);
// 头尾删除
d.pop_front();
d.pop_back();
// 清空元素
d.clear();
容量
size():获取元素个数;empty():判断是否为空;resize(n, val):调整容器大小,不足补val(默认 0);max_size():获取容器最大可容纳元素数(系统限制)。
deque<int> d = { 0, 1, 2, 3, 4, 5 };
// 获取元素数量
cout << d.size() << endl;
// 获取容器最大可容纳元素
cout << d.max_size() << endl;
遍历方式
- 下标遍历
deque<int> d = { 0, 1, 2, 3, 4, 5 };
// 下标遍历
for (int i = 0; i < d.size(); i++)
{
cout << d[i] << endl;
}
- 迭代器遍历
deque<int> d = { 0, 1, 2, 3, 4, 5 };
// 迭代器遍历
for (deque<int>::iterator it = d.begin(); it != d.end(); ++it)
{
cout << *it << endl;
}
- 范围for遍历(c++ 11)
deque<int> d = { 0, 1, 2, 3, 4, 5 };
// 增强for
for (int i : d)
{
cout << i << endl;
}
- 反向迭代器遍历
deque<int> d = { 0, 1, 2, 3, 4, 5 };
// 反向迭代器遍历
for (deque<int>::reverse_iterator it = d.rbegin(); it != d.rend(); ++it)
{
cout << *it << endl;
}
- for_each()遍历
deque<int> d = { 0, 1, 2, 3, 4, 5 };
for_each(d.begin(), d.end(), [](int val) {
cout << val << endl;
});
总结
- 核心定位:deque 是支持两端高效操作 + 随机访问的双端队列,平衡了 vector 和 list 的优缺点;
- 关键操作:push_front/pop_front、push_back/pop_back 是其核心优势(O(1) 时间复杂度);
- 使用选择:需要两端操作 + 随机访问选 deque;纯尾部操作 + 连续内存选 vector;大量中间操作选 list。