目录
deque
1. deque的成员函数
1.1 构造、析构和赋值运算符重载
1.1.1 构造函数
1.1.2 析构函数
1.1.3 赋值运算符重载
1.2 迭代器
1.3 容量
1.4 元素访问
1.4.1 遍历方法
1.5 修改器
1.6 空间配置器
2. deque的非成员函数
deque
deque(通常发音为 "deck")是双端队列的不规则缩写。双端队列是具有动态大小的序列容器,可以在两端(前端或后端)扩展或收缩。
特定的库可能以不同的方式实现deque,通常是某种形式的动态数组。但无论如何,它们都允许通过随机访问迭代器直接访问单个元素,并根据需要通过扩展和收缩容器自动处理存储。
因此,它们提供了与vector类似的功能,但可以在序列的开头(而不仅仅是结尾)有效地插入和删除元素。但是,与vector不同,deque不能保证将所有元素存储在连续的存储位置:通过偏移指向另一个元素的指针来访问deque中的元素会导致未定义的行为。
vector和deque都提供了非常相似的接口,可以用于类似的目的,但两者的内部工作方式截然不同: vector使用的是单个数组,偶尔需要重新分配以满足增长的需要,而deque的元素可以分散在不同的存储块中,容器内部保留了必要的信息,可以在恒定时间内通过统一的顺序接口(通过迭代器)直接访问其中的任何元素。因此,deque的内部结构要比vector复杂一些,但这使得它们在某些情况下能够更有效地增长,特别是在序列很长的情况下,重新分配的代价会更高。
对于在开头或结尾以外的位置频繁插入或移除元素的操作,deque的性能比list和forward_list差,迭代器和引用也不一致。
使用deque类模板要包含deque头文件;deque定义在命名空间std中。
1. deque的成员函数
1.1 构造、析构和赋值运算符重载
1.1.1 构造函数
重载函数 | 功能 |
---|---|
default | 构造空的deque类对象 |
fill | 用n个val来构造 |
range | 用迭代器区间[first,last)中的元素顺序构造 |
copy | 构造一个x的拷贝 |
move | 移动构造函数 |
initializer list | 用初始化列表来构造 |
#include <iostream>
#include <deque>
#include <string>
using namespace std;
int main()
{
deque<int> dq1;//default
for (size_t i = 0; i < dq1.size(); ++i)
{
cout << dq1[i] << " ";
}
cout << endl;
//空
deque<int> dq2(10, 1);//fill
for (size_t i = 0; i < dq2.size(); ++i)
{
cout << dq2[i] << " ";
}
cout << endl;
//1 1 1 1 1 1 1 1 1 1
string s("hello world");
deque<char> dq3(s.begin() + 3, --s.end());//range
for (size_t i = 0; i < dq3.size(); ++i)
{
cout << dq3[i] << " ";
}
cout << endl;
//l o w o r l
deque<char> dq4(dq3);//copy
//等价于deque<char> dq4 = dq3;
for (size_t i = 0; i < dq4.size(); ++i)
{
cout << dq4[i] << " ";
}
cout << endl;
//l o w o r l
deque<string> dq5{ "happy","new","year" };//initializer list
//等价于deque<string> dq5 = { "happy","new","year" };
for (size_t i = 0; i < dq5.size(); ++i)
{
cout << dq5[i] << " ";
}
cout << endl;
//happy new year
return 0;
}
1.1.2 析构函数
1.1.3 赋值运算符重载
1.2 迭代器
函数 | 功能 |
---|---|
begin & end | begin返回一个迭代器,指向deque对象的第一个元素 end返回一个迭代器,指向deque对象的最后一个元素的下一个位置 |
rbegin & rend | rbegin返回一个反向迭代器,指向deque对象的最后一个元素 rend返回一个反向迭代器,指向deque对象的第一个元素的上一个位置 |
cbegin & cend | cbegin返回一个const迭代器,指向deque对象的第一个元素 cend返回一个const迭代器,指向deque对象的最后一个元素的下一个位置 |
crbegin & crend | crbegin返回一个const反向迭代器,指向deque对象的最后一个元素 crend返回一个const反向迭代器,指向deque对象的第一个元素的上一个位置 |
begin&end和rbegin&rend返回的迭代器指向:
const_iterator是一个指向const内容的迭代器。迭代器本身可以修改,但是它不能被用来修改它所指向的内容。
begin&end/rbegin&rend和cbegin&cend/crbegin&crend的不同:
- begin&end/rbegin&rend的返回类型由对象是否是常量来决定。如果不是常量,返回iterator;如果是常量,返回const_iterator。
- cbegin&cend/crbegin&crend的返回类型是const_iterator,不管对象本身是否是常量。
#include <deque>
#include <iostream>
using namespace std;
int main()
{
deque<int> dq;
dq.push_back(1);
dq.push_back(2);
dq.push_back(3);
dq.push_back(4);
deque<int>::iterator it = dq.begin();
while (it != dq.end())
{
cout << *it << " ";
++it;
}
cout << endl;
//1 2 3 4
auto rit = dq.rbegin();
//deque<int>::reverse_iterator rit = dq.rbegin();
while (rit != dq.rend())
{
cout << *rit << " ";
++rit;
}
cout << endl;
//4 3 2 1
return 0;
}
1.3 容量
函数 | 功能 |
---|---|
size | 返回deque的元素个数 |
max_size | 返回deque所能容纳的最大元素数 |
resize | 调整deque的大小为n(影响size) ●如果n<当前deque的大小,多余的元素会被截掉 ●如果n>当前vdeque的大小,则: 1)如果没有指定填充元素,则在最后插入尽可能多的元素以达到n的大小 2)如果指定了填充元素val,则多出的空间用val填充 ●如果n也>当前deque的容量,则会自动重新分配存储空间 |
empty | 检测deque是否为空,是返回true,否则返回false |
shrink_to_fit | 收缩容量以适应deque的大小 这个请求没有约束力,容器实现可以自由地进行优化,使deque的容量大于其大小 |
#include <deque>
#include <iostream>
using namespace std;
int main()
{
deque<int> dq;
dq.push_back(1);
dq.push_back(2);
dq.push_back(3);
dq.push_back(4);
cout << dq.size() << endl;//4
cout << dq.max_size() << endl;//1073741823
dq.resize(8, 9);
for (size_t i = 0; i < dq.size(); ++i)
{
cout << dq[i] << " ";
}
cout << endl;
//1 2 3 4 9 9 9 9
if (dq.empty())
cout << "deque为空" << endl;
else
cout << "deque不为空" << endl;
//deque不为空
return 0;
}
1.4 元素访问
函数 | 功能 |
---|---|
operator[] | 返回deque中n位置的元素的引用 没有越界检查 |
at | 返回deque中n位置的元素的引用 有越界检查,如果越界会抛异常 |
front | 返回deque中第一个元素的引用 |
back | 返回deque中最后一个元素的引用 |
#include <deque>
#include <iostream>
using namespace std;
int main()
{
deque<int> dq;
dq.push_back(1);
dq.push_back(2);
dq.push_back(3);
dq.push_back(4);
cout << dq[0] << endl;//1
cout << dq.at(1) << endl;//2
cout << dq.front() << endl;//1
cout << dq.back() << endl;//4
return 0;
}
1.4.1 遍历方法
1.4.1.1 operator[](最常用)
#include <deque>
#include <iostream>
using namespace std;
int main()
{
deque<int> dq;
dq.push_back(1);
dq.push_back(2);
dq.push_back(3);
dq.push_back(4);
for (size_t i = 0; i < dq.size(); ++i)
{
cout << dq[i] << " ";
}
cout << endl;
//1 2 3 4
return 0;
}
1.4.1.2 迭代器
#include <deque>
#include <iostream>
using namespace std;
int main()
{
deque<int> dq;
dq.push_back(1);
dq.push_back(2);
dq.push_back(3);
dq.push_back(4);
deque<int>::iterator it = dq.begin();
while (it != dq.end())
{
cout << *it << " ";
++it;
}
cout << endl;
//1 2 3 4
auto rit = dq.rbegin();
//deque<int>::reverse_iterator rit = dq.rbegin();
while (rit != dq.rend())
{
cout << *rit << " ";
++rit;
}
cout << endl;
//4 3 2 1
return 0;
}
1.4.1.3 范围for
#include <deque>
#include <iostream>
using namespace std;
int main()
{
deque<int> dq;
dq.push_back(1);
dq.push_back(2);
dq.push_back(3);
dq.push_back(4);
for (auto e : dq)
{
cout << e << " ";
}
cout << endl;
//1 2 3 4
return 0;
}
1.5 修改器
函数 | 功能 |
---|---|
assign | 给deque赋值,替换其当前内容 |
push_back | 尾插 |
push_front | 头插 |
pop_back | 尾删 |
pop_front | 头删 |
insert | 在position位置之前插入 |
erase | 删除deque的一部分 |
swap | 交换内容 |
clear | 清空内容 |
emplace | 构建和插入元素 |
emplace_front | 在开头构建和插入元素 |
emplace_back | 在末尾构建和插入元素 |
#include <deque>
#include <iostream>
using namespace std;
int main()
{
deque<int> dq1{ 1,2,3,4 };
dq1.assign(3, 6);
for (size_t i = 0; i < dq1.size(); ++i)
{
cout << dq1[i] << " ";
}
cout << endl;
//6 6 6
dq1.push_back(1);
dq1.push_front(2);
for (size_t i = 0; i < dq1.size(); ++i)
{
cout << dq1[i] << " ";
}
cout << endl;
//2 6 6 6 1
dq1.pop_back();
dq1.pop_front();
for (size_t i = 0; i < dq1.size(); ++i)
{
cout << dq1[i] << " ";
}
cout << endl;
//6 6 6
dq1.insert(dq1.begin() + 1, 9);
for (size_t i = 0; i < dq1.size(); ++i)
{
cout << dq1[i] << " ";
}
cout << endl;
//6 9 6 6
dq1.erase(dq1.begin());
for (size_t i = 0; i < dq1.size(); ++i)
{
cout << dq1[i] << " ";
}
cout << endl;
//9 6 6
deque<int> dq2{ 8,8,8,8 };
dq1.swap(dq2);
for (size_t i = 0; i < dq1.size(); ++i)
{
cout << dq1[i] << " ";
}
cout << endl;
//8 8 8 8
dq1.clear();
if (dq1.empty())
cout << "dq1被清空" << endl;
else
cout << "dq1没被清空" << endl;
//dq1被清空
return 0;
}
1.6 空间配置器
函数 | 功能 |
---|---|
get_allocator | 获取空间配置器 |
2. deque的非成员函数
函数 | 功能 |
---|---|
relational operators | 关系运算符重载 |
swap | 交换内容 |