特殊队列
作者:互联网
特殊队列
双端队列
从名字可以看出,它可以在队列两端进行操作,相当于栈和队列的结合。主要操作有4种:
- 在队首插入一个元素
- 在队尾插入一个元素
- 在队首弹出一个元素
- 在队尾弹出一个元素
deque
C++的STL提供了一个容器std::deque
,使用时需要引入头文件<deque>
。
STL中的deque
容器包含一些成员函数,比较常用的有:
deque<int>deq;
//查询
deq.front(); //查询队首元素
deq.back(); //查询队尾元素
deq.empty(); //查询队列是否为空
deq.size(); //查询队列元素个数
//修改
deq.push_front(x); //队首插入一个元素
deq.pop_front(x); //队首删除一个元素
deq.push_back(x); //队尾插入一个元素
deq.pop_back(x); //队尾删除一个元素
deq.insert(i, x); //在指定为之前插入一个元素(传入迭代器和元素)
deq.erase(i); //删除指定位置的元素(传入迭代器)
另外,deque
还有一些运算符,比较常用的有:
- 用
=
为deque
赋值,类似queue
。 - 用
[]
查询deque
中的元素,类似vector
, 。
优先队列
头文件 queue
中提供了优先队列 std::priority_queue
,与二叉堆相似,可以维护顶部元素大小,默认维护最大值。每次维护(即删除和插入)的时间复杂度为\(O(\log n)\).
代码
//如果不使用using namespace std 名字空间,使用时应加上std::
std::priority_queue<int>heap;
int a[5] = {2, 1, 4, 5, 3};
//插入时的顶部元素最大值
for(int i = 0; i < 5; ++i){
heap.push(a[i]);
std::cout << heap.top() << ' '; //访问顶部元素
}
std::cout << '\n';
//输出:2 2 4 5 5
for(int i = 0; i < 5; ++i){
std::cout << heap.top() << ' '; //访问顶部元素
//弹出顶部元素
heap.pop();
}
//输出:5 4 3 2 1
例题
题目大意
给定 \(n\) 个数 \(a_{1\dots n}\),要求对它们从小到大排序。\((1 \leq n \leq 10^5\ , a_i \le 10^9)\)
题目思路
由上述可知优先队列可以维护最大值,所以可以进行排序,而这里需要从小到大排序,可以有几种解决方案,比如,将各个数的相反数加入优先队列中,或者先将答案从 \(n\) ~ 1 反向入数组中就可以了。优先队列每次操作的时间复杂度为 \(O(\log n)\) ,总的时间复杂度为 \(O(n\log n)\) ,是可以过的。
完整代码
//这里用第一种方法
#include<cstdio> //C语言风格
#include<iostream> //C++语言风格
#include<queue>
using namespace std;
int main(void){
priority_queue<int>heap;
int n;
scanf("%d", &n);
for(int i = 1; i <= n; ++i){
int a;
scanf("%d", &a);
//放入-a,访问时要用负号还原
heap.push(-a);
}
for(int i = 1; i <= n; ++i){
//注意,之前放入的是负数,使用时也应该先用负号还原成原来的数
printf("%d ", -heap.top());
heap.pop();
}
return 0;
}
标签:std,deque,特殊,队列,deq,元素,int 来源: https://www.cnblogs.com/yanyeting/p/16308993.html