C++ deque容器详解
C++ 标准库提供了很多种容器,其中 vector 容器可以使用下标随机访问元素,但插入、删除元素时效率较低;list容器则恰恰相反,插入、删除元素效率较高,但不能使用下标随机访问。
在 C++ 标准库中,deque(双端队列)是一种允许在两端进行插入和删除操作的容器。与 vector 和 list 容器不同,deque 容器既能使用下标随机访问元素,也能快速地在两端进行插入和删除。
下表罗列了 deque 模板类提供的所有成员函数。
下面的 C++ 程序演示了表中部分成员函数的用法:
运行程序,输出结果为:
在 C++ 标准库中,deque(双端队列)是一种允许在两端进行插入和删除操作的容器。与 vector 和 list 容器不同,deque 容器既能使用下标随机访问元素,也能快速地在两端进行插入和删除。
deque容器的构造
deque容器容器本质是一个模板类,定义在<deque>
头文件中。deque 模板类提供了多种构造函数,以便适应不同的应用场景,包括:// 创建一个空的deque容器 explicit deque (const allocator_type& alloc = allocator_type()); // 创建一个有 n 个元素的 deque,并进行默认初始化 explicit deque (size_type n); // 创建一个有 n 个元素的 deque,并初始化每个元素的值为 val deque (size_type n, const value_type& val, const allocator_type& alloc = allocator_type()); // 从另一个迭代器范围 [first, last) 创建一个 deque template <class InputIterator> deque (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()); //拷贝构造函数,创建一个与 x 相同的新 deque。 deque (const deque& x); deque (const deque& x, const allocator_type& alloc); //移动构造函数,创建一个新的 deque 容器,并从 x 中“移动”数据 deque (deque&& x); deque (deque&& x, const allocator_type& alloc); //从一个初始化列表 il 中复制元素到新的 deque 容器中 deque (initializer_list<value_type> il, const allocator_type& alloc = allocator_type());下面的 C++ 代码示例演示了如何使用 deque 容器的各种构造函数。
#include <iostream> #include <deque> #include <iterator> #include <vector> int main() { // 使用默认构造函数创建一个空的 deque std::deque<int> emptyDeque; std::cout << "Empty deque size: " << emptyDeque.size() << std::endl; // 创建一个包含 5 个元素的 deque,默认初始化为0 std::deque<int> dequeWithFiveElements(5); std::cout << "Deque with 5 elements (default initialized): "; for (auto x : dequeWithFiveElements) std::cout << x << " "; std::cout << std::endl; // 创建一个包含 5 个元素的 deque,每个元素初始化为3 std::deque<int> dequeWithFiveThrees(5, 3); std::cout << "Deque with 5 elements (each set to 3): "; for (auto x : dequeWithFiveThrees) std::cout << x << " "; std::cout << std::endl; // 使用迭代器创建一个 deque std::vector<int> vec = {1, 2, 3, 4, 5}; std::deque<int> dequeFromIterators(vec.begin(), vec.end()); std::cout << "Deque from iterators: "; for (auto x : dequeFromIterators) std::cout << x << " "; std::cout << std::endl; // 使用拷贝构造函数创建一个新的 deque std::deque<int> dequeCopy(dequeFromIterators); std::cout << "Deque from copy constructor: "; for (auto x : dequeCopy) std::cout << x << " "; std::cout << std::endl; // 使用移动构造函数创建一个新的 deque std::deque<int> dequeMoved(std::move(dequeCopy)); std::cout << "Deque from move constructor: "; for (auto x : dequeMoved) std::cout << x << " "; std::cout << std::endl; // 使用初始化列表创建一个新的 deque std::deque<int> dequeFromInitList = {10, 20, 30, 40, 50}; std::cout << "Deque from initializer list: "; for (auto x : dequeFromInitList) std::cout << x << " "; std::cout << std::endl; return 0; }运行结果为:
Empty deque size: 0
Deque with 5 elements (default initialized): 0 0 0 0 0
Deque with 5 elements (each set to 3): 3 3 3 3 3
Deque from iterators: 1 2 3 4 5
Deque from copy constructor: 1 2 3 4 5
Deque from move constructor: 1 2 3 4 5
Deque from initializer list: 10 20 30 40 50
deque容器的使用
和 vector 容易类似,deque 容器也能够快速随时访问元素。在插入、删除元素方面,deque 容器更擅长的是操作两端的元素,而操作中间位置元素的效率较低。下表罗列了 deque 模板类提供的所有成员函数。
函数成员 | 函数功能 |
---|---|
begin() | 返回指向容器中第一个元素的迭代器。 |
end() | 返回指向容器最后一个元素所在位置后一个位置的迭代器,通常和 begin() 结合使用。 |
rbegin() | 返回指向最后一个元素的迭代器。 |
rend() | 返回指向第一个元素所在位置前一个位置的迭代器。 |
cbegin() | 和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。 |
cend() | 和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。 |
crbegin() | 和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。 |
crend() | 和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。 |
size() | 返回实际元素个数。 |
max_size() | 返回容器所能容纳元素个数的最大值。这通常是一个很大的值,一般是 232-1,我们很少会用到这个函数。 |
resize() | 改变实际元素的个数。 |
empty() | 判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。 |
shrink _to_fit() | 将内存减少到等于当前元素实际所使用的大小。 |
at() | 使用经过边界检查的索引访问元素。 |
front() | 返回第一个元素的引用。 |
back() | 返回最后一个元素的引用。 |
assign() | 用新元素替换原有内容。 |
push_back() | 在序列的尾部添加一个元素。 |
push_front() | 在序列的头部添加一个元素。 |
pop_back() | 移除容器尾部的元素。 |
pop_front() | 移除容器头部的元素。 |
insert() | 在指定的位置插入一个或多个元素。 |
erase() | 移除一个元素或一段元素。 |
clear() | 移出所有的元素,容器大小变为 0。 |
swap() | 交换两个容器的所有元素。 |
emplace() | 在指定的位置直接生成一个元素。 |
emplace_front() | 在容器头部生成一个元素。和 push_front() 的区别是,该函数直接在容器头部构造元素,省去了复制移动元素的过程。 |
emplace_back() | 在容器尾部生成一个元素。和 push_back() 的区别是,该函数直接在容器尾部构造元素,省去了复制移动元素的过程。 |
下面的 C++ 程序演示了表中部分成员函数的用法:
#include <iostream> #include <deque> int main() { std::deque<int> deq; // 尾部插入 deq.push_back(1); deq.push_back(2); // 头部插入 deq.push_front(0); deq.push_front(-1); // 随机访问 std::cout << "第一个元素: " << deq[0] << std::endl; std::cout << "第四个元素: " << deq[3] << std::endl; // 删除 deq.pop_back(); deq.pop_front(); // 遍历 for(int i : deq) { std::cout << i << " "; } std::cout << std::endl; return 0; }示例中演示了 deque 的一些基本操作,比如尾部插入 (push_back)、头部插入(push_front)、随机访问 (operator[])和两端删除(pop_back 和 pop_front)。
运行程序,输出结果为:
第一个元素: -1
第四个元素: 2
0 1