文章目录
1.deque容器
1.1 介绍
双端队列
Deque(通常发音像“deck”)是双端队列的不规则首字母缩写。双端队列是具有动态大小的序列容器,可以在两端(前端或后端)进行扩展或收缩。
特定的库可能以不同的方式实现deques,通常是作为某种形式的动态数组。但在任何情况下,它们都允许通过随机访问迭代器直接访问单个元素,并根据需要通过扩展和收缩容器自动处理存储。
因此,它们提供了类似于向量的功能,但可以在序列的开头高效地插入和删除元素,而不仅仅是在序列的末尾。但是,与vector不同,deque不能保证将其所有元素存储在连续的存储位置:通过偏移指向另一个元素的指针来访问deque中的元素会导致未定义的行为。
vector和deque都提供了非常相似的接口,也可以用于类似的目的,但在内部它们的工作方式却截然不同:vector使用一个单独的数组,需要偶尔重新分配以实现增长,而deque的元素可以分散在不同的存储块中,容器在内部保存必要的信息,以便在恒定的时间内通过统一的顺序接口(通过迭代器)直接访问其任何元素。因此,deque在内部比vector更复杂一些,但这允许它们在某些情况下更有效地增长,特别是对于非常长的序列,在这种情况下重新分配会变得更昂贵。
对于频繁插入或删除开始或结束位置以外的元素的操作,deque的性能较差,迭代器和引用的一致性不如列表和转发列表。
1.2 简单解析
A. 头文件: ”queue“ 或者 ”deque“
B. 双端队列:支持队头队尾双向快速插入 / 删除元素(相对于普通队列可以额外支持队头的插入删除) + 快速随机访问元素(类似于向量容器Vector)
C. 常用场景:处理问题需要对一个队列频繁队尾队头修改时可以使用。
2.迭代器操作(Iterator)
deque.begin() —— 返回容器头部元素迭代器
deque.end() —— 返回容器尾部元素下一位置的迭代器
#include<iostream>
#include<queue>
using namespace std;
int main(){
deque<int> dq;
for(int i = 0; i < 7; i ++ ){
dq.push_back(i);
}
for(auto it = dq.begin(); it != dq.end(); it ++ ){
cout << *it << ' ';
}
// 输出 : 0 1 2 3 4 5 6
}
3.容量操作(Capacity)
deque.empty() —— 返回容器是否为空,为空返回True,否则为 false
deque.size() —— 返回容器内部元素个数
deque.max_size() —— 返回容器最大存储容量
#include<iostream>
#include<queue>
using namespace std;
int main(){
deque<int> dq;
for(int i = 0; i < 7; i ++ ){
dq.push_back(i);
}
if(dq.empty() == false){
puts("队列不为空");
} // 输出; 队列不为空
cout << dq.size() << endl;
// 输出: 7
cout << dq.max_size() << endl;
// 输出: 4611686018427387903
}
4.访问操作(Element access)
deque[ ]—— 访问指定位置元素
deque.at() —— 访问指定位置元素
deque.front() —— 返回容器队头元素
deque.back() —— 返回容器队尾元素
#include<iostream>
#include<queue>
using namespace std;
int main(){
deque<int> dq;
for(int i = 0; i < 7; i ++ ){
dq.push_back(i);
}
for(int i = 0; i < 7; i ++ ){
cout << dq.at(i) << ' '; // cout << dq[i] << ' ';
}
cout << '\n';
// 输出: 0 1 2 3 4 5 6
cout << dq.front() << ' ' << dq.back() << endl;
// 输出: 0 6
}
5.修改操作(Modifiers)
deque.assign(n, val) —— 初始化n 个 val值
deque.assign(first_iterator, end_iterator) ——将迭代器范围内值初始化给deque
#include<iostream>
#include<queue>
using namespace std;
int main(){
deque<int> dq;
int a[] = {0, 1, 2};
dq.assign(5, 3); // n * val
for(auto it = dq.begin(); it != dq.end(); it ++ ){
cout << *it << ' '; // 3 3 3 3 3
}
cout << '\n';
dq.assign(a, a + 3); // 初始位置, 结束位置
for(auto it = dq.begin(); it != dq.end(); it ++ ){
cout << *it << ' '; // 0 1 2
}
}
push_back(),pop_back() —— 队尾增加,删除元素
push_front(),pop_front() —— 队头增加,删除元素
#include<iostream>
#include<queue>
using namespace std;
int main(){
deque<int> dq;
for(int i = 0; i < 3; i ++ ){
dq.push_back(i);
}
dq.pop_back();
for(int i = 0; i < dq.size(); i ++ ){
cout << dq[i] << ' ';
} // 输出: 0 1
}
deque.insert(position_iterator, val) —— 向指定位置插入一个值为val元素
deque.insert(position_iterator, n, val) —— 向指定位置插入n个值为val元素
deque.insert(position_iterator, first_iterator, end_iterator) —— 向指定位置插入[first, end)范围内元素
deque.erase(position_iterator) —— 删除指定位置元素
deque.erasse(first_iterator, end_iterator) —— 删除[first, end)范围内元素
#include<iostream>
#include<queue>
using namespace std;
int main(){
deque<int> dq;
int a[] = {100, 10};
dq.assign(1, 1);
dq.insert(dq.begin(), 0);
for(auto it = dq.begin(); it != dq.end(); it ++ ){
cout << *it << ' ';
} // 输出; 0 1
cout << '\n';
dq.insert(dq.begin(), 2, 2);
for(auto it = dq.begin(); it != dq.end(); it ++ ){
cout << *it << ' ';
} // 输出; 2 2 0 1
cout << '\n';
dq.insert(dq.begin(), a, a + 2);
for(auto it = dq.begin(); it != dq.end(); it ++ ){
cout << *it << ' ';
} // 输出; 100 10 2 2 0 1
cout << '\n';
dq.erase(dq.begin() + 1);
for(auto it = dq.begin(); it != dq.end(); it ++ ){
cout << *it << ' ';
} // 输出; 100 2 2 0 1
cout << '\n';
dq.erase(dq.begin(), dq.begin() + 3);
for(auto it = dq.begin(); it != dq.end(); it ++ ){
cout << *it << ' ';
} // 输出; 0 1
cout << '\n';
}
deque.clear() —— 清空容器内所有元素
deque.swap() —— 交换双端队列容器内部元素
#include<iostream>
#include<queue>
using namespace std;
int main(){
deque<int> dq, dq2;
int a[] = {1, 2, 3, 4, 5};
dq.assign(a, a + 5);
swap(dq, dq2);
cout << dq.size() << endl; // 输出: 0
for(auto it = dq2.begin(); it != dq2.end(); it ++ ){
cout << *it << ' ';
} // 输出; 1 2 3 4 5
cout << '\n';
dq2.clear();
cout << dq2.size() << endl; // 输出; 0
}