优先队列priority_queue,
底层是用堆实现的,
队首元素总是优先级最大的。
头文件+命名空间:
#include <queue>
using namespace std;
定义:
priority_queue<typename> name;
一、元素优先级的设置
1.基本数据类型优先级设置
默认是int,double型等数字大的优先级高,char型等按字典序
priority_queue<int> q;
priority_queue<int, vector<int>,less<int> > q; //特别注意最后两个>之间有空格
第二种定义方式:
第二个参数:用来承载底层数据结构堆(heap)的容器
第三个参数:对第一个参数的比较类
less<int> :数字大的优先级大
greater<int>:数字小的优先级大
//最大堆
priority_queue<int, vector<int>, less<int> > q;
//最小堆
priority_queue<int, vector<int>, greater<int> > q;
2.结构体优先级设置
法1:运算符重载
struct fruit
{
string name;
int price;
friend bool operator < (fruit f1,fruit f2){
return f1.price < f2.price;//最大堆
}
};
重载大于号会编译错误,因为从数学上来说只需要重载小于号
f1>f2 → f2<f1
f1==f2 → !(f1<f2)&&!(f2<f1)
跟cmp函数规则相反
return f1.price<f2.price; 价格高的优先级高
return f1.price>f2.price; 价格低的优先级高
法2:类似cmp函数
struct fruit
{
string name;
int price;
};
struct cmp
{
bool operator () (fruit f1,fruit f2){
return f1.price < f2.price;//最大堆
}
};
priority_queue<fruit, vector<fruit>, cmp> q;//最大堆,把less<>换成了cmp
此时定义的类似cmp函数的struct结构体,跟重载效果一样,
仍然与之前的cmp函数规则相反
即使是基本数据类型或者其他STL容器(例如set),
也可以通过同样的方式来定义优先级。
如果结构体内的数据较为庞大(例如出现了字符串或者数组),建议使用引用来提高效率。
这时,比较类的参数中需要加上"const"和"&"
friend bool operator < (const fruit &f1,const fruit &f2) {
return f1.price > f2.price;
}
struct cmp{
bool operator () (const fruit &f1,const fruit &f2){
return f1.price < f2.price;
}
};
二、常用函数:
(1) push()
入队操作,时间复杂度为O(logN)
q.push(x);
(2) top()
注意要先判空,防止队空导致错误
获取堆顶元素(队首元素),时间复杂度为O(1)
cout<<q.top();
(3) pop()
注意要先判空,防止队空导致错误
令堆顶元素(队首元素)出队,时间复杂度为O(logN)
q.pop();
(4) empty()
检测优先队列是否为空,
返回true则空,返回false则非空
时间复杂度为O(1)
if(!q.empty()){
printf("Not Empty.\n");
}
(5) size()
返回优先队列中的元素个数,时间复杂度为O(1)
三、常见用途
- 解决一些贪心问题
- 对dijkstra算法进行优化(优先队列的本质是堆)