1.介绍
deque(双端队列)是C++标准库中的一个容器,支持在队列的两端高效的插入与删除元素。它结合了vector和list的优点。即支持随机访问、又支持高效的双端操作。
2.deque的基本特性
-
双端操作:可以在队列的前端和后端高效地插入和删除元素。
-
随机访问:支持通过下标(
[]
)或at()
方法访问元素。 -
动态扩展:与
vector
类似,deque
可以动态扩展,但它的内存布局是分块的,因此在扩展时不需要像vector
那样复制所有元素。 -
性能:
-
在两端插入和删除的时间复杂度为 O(1)。
-
随机访问的时间复杂度为 O(1)。
-
在中间插入和删除的时间复杂度为 O(n)。
-
3.deque的用法
(1)声明与初始化
#include <deque>
int main() {
// 默认初始化
std::deque<int> dq1;
// 初始化包含 5 个元素,每个元素的值为 10
std::deque<int> dq2(5, 10); // dq2: [10, 10, 10, 10, 10]
// 使用初始化列表
std::deque<int> dq3 = {1, 2, 3, 4, 5}; // dq3: [1, 2, 3, 4, 5]
// 使用其他容器初始化
std::deque<int> dq4(dq3.begin(), dq3.end()); // dq4: [1, 2, 3, 4, 5]
return 0;
}
(2)插入元素
//尾插
dq1.push_back(10); // dq1: [10]
dq1.push_back(20); // dq1: [10, 20]
//头插
dq1.push_front(5); // dq1: [5, 10, 20]
//指定位置插入
auto it = dq1.begin() + 1;
dq1.insert(it, 15); // dq1: [5, 15, 10, 20]
(3)删除元素
//尾删
dq1.pop_back(); // dq1: [5, 15, 10]
//头删
dq1.pop_front(); // dq1: [15, 10]
//删除指定位置
auto it = dq1.begin() + 1;
dq1.erase(it); // dq1: [15]
(3)访问元素
//下标访问
std::cout << dq1[0] << std::endl; // 输出: 15
//at()访问
std::cout << dq1.at(0) << std::endl; // 输出: 15
//访问头部和尾部
std::cout << "Front: " << dq1.front() << std::endl; // 输出: 15
std::cout << "Back: " << dq1.back() << std::endl; // 输出: 15
(4)检查是否为空
if (dq1.empty()) {
std::cout << "Deque is empty." << std::endl;
}
(5)获取大小
std::cout << "Deque size: " << dq1.size() << std::endl;
(6)清空容器
dq1.clear(); // 清空所有元素
4.deque的底层实现
deque的底层实现通常是一个分块的动态数组。它将数据存储在多个固定大小的块中,并通过一个中央控制器管理这些块。这种设计使得deque在两端插入和删除时非常高效,同时支持随机访问。
5.deque和vector对比
特性 | deque | vector |
随机访问 | 支持,O(1) | 支持,O(1) |
头部插入/删除 | 高效,O(1) | 低效,O(n) |
尾部插入/删除 | 高效,O(1) | 高效,O(1) |
中间插入/删除 | 低效,O(n) | 低效,O(n) |
内存布局 | 分块存储 | 连续存储 |
扩展方式 | 无需复制所有元素 | 可能需要复制所有元素 |
6.应用场景
-
需要频繁在两端插入和删除元素的场景。
-
实现滑动窗口算法。
-
作为
stack
和queue
的底层容器。
7.总结
deque容器作为C++的标准容器之一,是经常被使用的。掌握其用法和特性能够使编写代码事半功倍。
如有错误,敬请指正!!!