欢迎前往我的个人博客阅读原文。
deque 双端队列容器和 vector 向量容器相同的是采用的都是线性表顺序存储结构;不同的是 deque 双端队列容器采用分块的线性存储结构来存储数据,每块的大小一般为 512 字节,称为一个 deque 块,所有的 deque 块使用一个 Map 块进行管理,每个 Map 数据项记录各个 deque 块的首地址。
deque 块在头部和尾部都可插入和删除元素:使用 push_back()
方法在尾部插入元素,会扩张队列;使用 push_front()
方法在首部插入元素;使用 insert()
方法在中间插入元素。在考虑容器元素的容器内存分配策略和操作的性能的情况下,deque 相当于 vector 更有优势。
使用 deque 双端队列容器需要声明头文件:
#include<deque>
创建 deque 对象
创建 deque 对象和创建 vector 对象类似,一般有三种方法:
- 创建没有任何元素的 deque 对象:
deque<int> d;
deque<float> dd;
- 创建具有 n 个元素的 deque 对象:
deque<int> d(10);
- 创建具有 n 个元素的 deque 对象,并赋初值:
deque<float> d(10, 8.5);
插入元素
- 使用
push_back()
方法从尾部插入元素,会不断扩张队列。
#include<deque>
#include<iostream>
using namespace std;
int main(int argc, char* argv[])
{
// 定义 deque 对象,元素类型是整型
deque<int> d;
// 从尾部连续插入三个元素
d.push_back(1);
d.push_back(2);
d.push_back(3);
// 以数组方式输出元素
cout << d[0] << ' ' << d[1] << ' ' << d[2] << endl;
return 0;
}
运行结果:
- 从头部插入元素,不会增加新元素,只将原有的元素覆盖。
#include<deque>
#include<iostream>
using namespace std;
int main(int argc, char* argv[])
{
deque<int> d;
d.push_back(1);
d.push_back(2);
d.push_back(3);
// 从头部插入元素,不会添加新元素,只讲原有的元素覆盖
d.push_front(10);
d.push_front(20);
cout << d[0] << ' ' << d[1] << ' ' << d[2] << endl;
return 0;
}
输出结果:
- 从中间插入元素,不会增加新元素,只将原有的元素覆盖。
#include<deque>
#include<iostream>
using namespace std;
int main(int argc, char* argv[])
{
deque<int> d;
d.push_back(1);
d.push_back(2);
d.push_back(3);
// 中间插入元素,不会增加新元素,只讲原有的元素覆盖
d.insert(d.begin() + 1, 88);
cout << d[0] << ' ' << d[1] << ' ' << d[2] << endl;
return 0;
}
运行结果:
使用
insert()
方法也是要使用迭代器的,和前面几种容器使用方法一样。
前向遍历
根据前面的经验,前向遍历显然有两种方式,一种以数组方式遍历,一种以迭代器方式遍历。
- 以数组方式遍历。
#include<deque>
#include<iostream>
using namespace std;
int main(int argc, char* argv[])
{
deque<int> d;
d.push_back(1);
d.push_back(2);
d.push_back(3);
int i;
for (i = 0; i < d.size(); i++)
cout << d[i] << ' ';
cout << endl;
return 0;
}
- 以迭代器方式遍历
#include<deque>
#include<iostream>
using namespace std;
int main(int argc, char* argv[])
{
deque<int> d;
d.push_back(1);
d.push_back(2);
d.push_back(3);
deque<int>::iterator it;
for (it = d.begin(); it != d.end(); it++)
cout << *it << ' ';
cout << endl;
return 0;
}
运行结果:
反向遍历
利用反向迭代器对双端队列容器进行反向遍历:
#include<deque>
#include<iostream
using namespace std;
int main(int argc, char* argv[])
{
deque<int> d;
d.push_back(1);
d.push_back(2);
d.push_back(3);
deque<int>::reverse_iterator rit;
for (rit = d.rbegin(); rit != d.rend(); rit++)
cout << *rit << ' ';
cout << endl;
return 0;
}
输出结果:
删除元素
删除元素可以从双端队列容器的首部、尾部、中部进行,另外,可以清空双端队列容器。
- 采用
pop_front()
方法从头部删除元素。
#include<deque>
#include<iostream>
using namespace std;
int main(int argc, char* argv[])
{
deque<int> d;
d.push_back(1);
d.push_back(2);
d.push_back(3);
d.push_back(4);
d.push_back(5);
// 从头部删除元素
d.pop_front();
d.pop_front();
deque<int>::iterator it;
for (it = d.begin(); it != d.end(); it++)
cout << *it << ' ';
cout << endl;
return 0;
}
运行结果:
- 采用
pop_back()
方法从尾部删除元素。
#include<deque>
#include<iostream>
using namespace std;
int main(int argc, char* argv[])
{
deque<int> d;
d.push_back(1);
d.push_back(2);
d.push_back(3);
d.push_back(4);
d.push_back(5);
// 从尾部删除元素
d.pop_back();
deque<int>::iterator it;
for (it = d.begin(); it != d.end(); it++)
cout << *it << ' ';
cout << endl;
return 0;
}
运行结果:
- 使用
erase()
方法从中间删除元素,其参数是迭代器位置。
#include<deque>
#include<iostream>
using namespace std;
int main(int argc, char* argv[])
{
deque<int> d;
d.push_back(1);
d.push_back(2);
d.push_back(3);
d.push_back(4);
d.push_back(5);
// 从中间删除元素,erase 的参数是迭代器位置
d.erase(d.begin() + 1);
deque<int>::iterator it;
for (it = d.begin(); it != d.end(); it++)
cout << *it << ' ';
cout << endl;
return 0;
}
运行结果:
- 使用
clear()
方法清空 deque 对象。
#include<deque>
#include<iostream>
using namespace std;
int main(int argc, char* argv[])
{
deque<int> d;
d.push_back(1);
d.push_back(2);
d.push_back(3);
d.push_back(4);
d.push_back(5);
// 清空元素
d.clear();
// 输出元素个数
cout << d.size() << endl;
return 0;
}
运行结果:
deque 的简单知识就差不多了,C++ STL 中的容器大同小异,只需要记住一些特定的方法就可以了。