目录
优先队列介绍
- 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出的行为特征。
- priority_queue 优先队列,其底层是用堆来实现的。在优先队列中,队首元素一定是当前队列中优先级最高的那一个。
- 最大优先队列,无论入队顺序,当前最大的元素优先出队。最小优先队列,无论入队顺序,当前最小的元素优先出队。
- 最大堆的堆顶是整个堆中的最大元素;最小堆的堆顶是整个堆中的最小元素。因此,可以用最大(小)堆来实现最大(小)优先队列,每一次入队操作就是堆的插入操作,每一次出队操作就是删除堆顶节点。
- 综上,优先队列出队和入队即为二叉堆节点的调整,所以时间复杂度都是O(logN)
优先队列声明
基本格式是:priority_queue<结构类型> 队列名;
priority_queue<Type, Container, Functional> pq_name;
共有三个参数:Type 为数据类型,Container为保存数据的容器,Functional 为元素比较方式。(后面两个参数都可省略)
priority_queue <int,vector<int>,less<int> > pq_less;
priority_queue <int,vector<int>,greater<int> > pq_great;
- priority_queue的声明,priority_queue包含在#include <queue> 头文件中
- 最后面两个">"不要写在一起,它们之间是有空格的,">>"是右移运算符
- 数据容器container可以为vector(默认)、deque等等,但不能用 list,若省略则缺省值为vector
- less<int>是从大到小(默认),greater<int>是从小到大,若省略则缺省值为less,即优先队列为大顶堆,队头元素最大
- 优先队列的特性是自动排序
声明为自定义结构类型node
priority_queue <node> pq;
node是一个结构体,可以在结构体中重载
下面这个例子中重载了操作符"<",使得重载规则变更为,结构体成员x小的node小
#include<iostream>
#include<queue>
using namespace std;
struct node
{
int x,y;
bool operator < (const node & a) const
{
return x<a.x;
}
};
int main(){
priority_queue<node> pq;
node k;
k.x=2, k.y=100; pq.push(k);
k.x=4, k.y=80; pq.push(k);
k.x=6, k.y=60; pq.push(k);
while(!pq.empty()){
k = pq.top();
pq.pop();
cout << k.x << ", " << k.y << endl;
}
return 0;
}
输出结果:
6, 60 //x最大
4, 80
2, 100 //x最小
优先队列各类操作
在优先队列中,没有 front() 函数与 back() 函数,而只能通过 top() 函数来访问队首元素(即堆顶元素),也就是优先级最高的元素。
q.size(); //返回q里元素个数
q.empty(); //返回q是否为空,空则返回1,否则返回0
q.push(k); //在q的末尾插入k
q.pop(); //删掉q的第一个元素
q.top(); //返回q的第一个元素
pair的比较函数
STL的pair<T1,T2>具有与生俱来的排序能力。其中T1和T2是两个对象,两个pair对象的比较规则:先比较第一个参数,如果第一个参数相同再比较第二个参数,以此类推。
如下面例子中的pair对象具有两个参数(pair<int,char>),第一个为int,第二个为char。
#include<iostream>
#include<queue>
using namespace std;
int main(){
priority_queue<pair<int,char> > pq;
pair<int,char> a(3,'Z');
pair<int,char> b(3,'S');
pair<int,char> c(4,'D');
pq.push(a);
pq.push(b);
pq.push(c);
while(!pq.empty()){
cout<<pq.top().first<<","<<pq.top().second<<endl;
pq.pop();
}
return 0;
}
输出结果:
4,D //对应c
3,Z //对应a
3,S //对应b