在C++的标准模板库(STL)中,deque
(双端队列)是一种双向队列,它提供了高效的随机访问、高效的头部和尾部插入/删除操作,是一种非常实用的容器。
1. Deque容器的特性
- 双端队列:
deque
是一种双端队列,支持在队列的头部和尾部进行快速插入和删除操作。 - 动态数组:
deque
底层使用了动态数组实现,使得其支持高效的随机访问。 - 内存分段:
deque
内部采用了一种分段的数据结构,使得在头部和尾部进行插入和删除操作时具有高效性能。 - 不连续存储:
deque
的元素在内存中不是连续存储的,每个分段内的元素是连续存储的。
2. Deque容器的优缺点
-
优点:
- 高效的随机访问,支持常数时间复杂度的随机访问操作。
- 高效的头部和尾部插入/删除操作,支持常数时间复杂度的插入和删除操作。
- 支持动态扩容和缩容,可以根据需要动态分配内存空间。
- 不会失效的迭代器,插入和删除操作不会导致迭代器失效。
-
缺点:
- 相比于
vector
,deque
在内存分配和管理上存在一定的开销。 - 不支持在中间位置进行插入和删除操作,这是由于
deque
的数据结构所决定的。 - 不支持指针和引用的算术运算,这是由于
deque
的内存分段结构所导致的。
- 相比于
3. Deque容器的适用场景
- 数据缓存: 适用于需要高效插入和删除操作的数据缓存场景。
- 任务队列: 适用于需要实现任务队列的场景,支持高效的任务入队和出队操作。
- 消息队列: 适用于需要实现消息队列的场景,支持高效的消息入队和出队操作。
- 历史记录: 适用于需要保存历史记录并支持快速访问的场景,如浏览器历史记录。
4. 使用Deque容器的方法
使用deque
容器非常简单,只需要包含头文件<deque>
,然后通过创建deque
对象并调用其成员函数来进行操作。以下是一些常见的操作方法:
- 创建deque: 使用
deque
的构造函数或赋值运算符来创建一个deque
对象。 - 插入元素: 使用
push_back()
、push_front()
或insert()
函数在deque
中插入元素。 - 删除元素: 使用
pop_back()
、pop_front()
或erase()
函数删除deque
中的元素。 - 访问元素: 使用迭代器或
front()
、back()
函数来访问deque
中的元素。 - 遍历元素: 使用迭代器或范围循环来遍历
deque
中的元素。
5.部分成员函数介绍
// 构造函数,创建一个空的deque容器
deque();
// 构造函数,创建一个包含n个元素的deque容器,每个元素的值都是value
explicit deque(size_type n, const value_type& value = value_type());
// 将另一个deque容器的元素拷贝到当前容器中
deque(const deque& other);
// 析构函数,释放deque容器所占用的资源
~deque();
// 从deque容器中删除所有元素,使其大小变为0
void clear() noexcept;
// 返回当前deque容器中的元素个数
size_type size() const noexcept;
// 返回当前deque容器是否为空
bool empty() const noexcept;
// 在deque容器的尾部插入一个元素
void push_back(const value_type& value);
// 在deque容器的头部插入一个元素
void push_front(const value_type& value);
// 从deque容器的尾部删除一个元素
void pop_back();
// 从deque容器的头部删除一个元素
void pop_front();
// 返回deque容器的第一个元素的引用
reference front();
// 返回deque容器的第一个元素的常量引用
const_reference front() const;
// 返回deque容器的最后一个元素的引用
reference back();
// 返回deque容器的最后一个元素的常量引用
const_reference back() const;
// 交换当前deque容器和另一个deque容器的内容
void swap(deque& other) noexcept;
// 删除deque容器中指定位置的元素
iterator erase(const_iterator position);
// 删除deque容器中指定范围内的元素
iterator erase(const_iterator first, const_iterator last);
// 在deque容器中指定位置插入一个元素
iterator insert(const_iterator position, const value_type& value);
// 在deque容器中指定位置插入n个相同的元素
iterator insert(const_iterator position, size_type n, const value_type& value);
// 在deque容器中指定位置插入范围内的元素
template <typename InputIt>
iterator insert(const_iterator position, InputIt first, InputIt last);
6.示例代码
#include <iostream>
#include <deque>
#include <algorithm>
#include <numeric>
int main() {
// 创建一个deque并初始化
std::deque<int> myDeque = { 5, 2, 8, 3, 1, 6 };
// 使用迭代器遍历deque并打印元素
std::cout << "Deque elements: ";
for (int num : myDeque) {
std::cout << num << " ";
}
std::cout << std::endl;
// 使用push_back和push_front在deque的尾部和头部插入元素
myDeque.push_back(10);
myDeque.push_front(20);
// 在deque的中间位置插入元素
auto it = myDeque.begin();
std::advance(it, 3); // 将迭代器移动到第4个元素的位置
myDeque.insert(it, 10); // 在第4个元素的位置插入元素10
// 使用迭代器访问deque中的元素
std::cout << "Deque elements using iterators: ";
for (auto it = myDeque.begin(); it != myDeque.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 使用pop_back和pop_front从deque的尾部和头部删除元素
myDeque.pop_back();
myDeque.pop_front();
// 使用算法对deque进行操作
// 1. 排序算法
std::sort(myDeque.begin(), myDeque.end());
std::cout << "Sorted deque elements: ";
for (int num : myDeque) {
std::cout << num << " ";
}
std::cout << std::endl;
// 2. 查找算法
int target = 3;
it = std::find(myDeque.begin(), myDeque.end(), target);
if (it != myDeque.end()) {
std::cout << "Element " << target << " found in deque" << std::endl;
}
else {
std::cout << "Element " << target << " not found in deque" << std::endl;
}
// 查找最大值
int maxElement = *std::max_element(myDeque.begin(), myDeque.end());
std::cout << "Maximum element in deque: " << maxElement << std::endl;
// 计算元素和
int sum = std::accumulate(myDeque.begin(), myDeque.end(), 0);
std::cout << "Sum of elements in deque: " << sum << std::endl;
// 反转元素
std::reverse(myDeque.begin(), myDeque.end());
// 打印反转后的deque元素
std::cout << "Deque elements after reverse: ";
for (int num : myDeque) {
std::cout << num << " ";
}
std::cout << std::endl;
// 查找特定值
target = 4;
auto it_target = std::find(myDeque.begin(), myDeque.end(), target);
if (it_target != myDeque.end()) {
std::cout << "Element " << target << " found in deque" << std::endl;
}
else {
std::cout << "Element " << target << " not found in deque" << std::endl;
}
// 计算元素平均值
double average = static_cast<double>(std::accumulate(myDeque.begin(), myDeque.end(), 0)) / myDeque.size();
std::cout << "Average of elements in deque: " << average << std::endl;
return 0;
}