简介
priority_queue又称为优先队列,其底层是用堆来进行实现的。
在优先队列中,队首元素一定是当前队列中优先级最高的那一个。
当然,可以在任何时候往优先队列里面加入(push)元素,而优先队列底层的数据结构堆(heap)会随时调整结构,使得每次的队首元素都是优先级最大的。
定义
priority_queue<typename> name;
方法
和队列不一样的是,优先队列没有front()和back()函数,而只能通过top()函数来访问队首元素。
它的方法有:
- push()
- top() : 可以获得队首元素(即堆顶元素)
- pop() : 队首元素(即堆顶元素)出队
- empty()
- size()
#include<iostream>
#include<queue>
using namespace std;
int main(){
priority_queue<int> q;
q.push(3);
q.push(4);
q.push(1);
cout << q.top() << endl; // 4
q.pop();
cout << q.top(); // 3
return 0;
}
优先级的设置
(1) 基本数据类型的优先级设置
priority_queue<int, vector<int>, less<int> > q;
priority_queue<int, vector<int>, greater<int> > q;
less表示数字大的优先级越大(建立最大堆)
greater表示数字小的优先级越大(建立最小堆)
vector是用来承载底层数据结构堆(heap)的容器
#include<iostream>
#include<queue>
using namespace std;
int main(){
priority_queue<int, vector<int>, greater<int>> q;
q.push(3);
q.push(4);
q.push(1);
cout << q.top(); // 1
return 0;
}
(2) 结构体的优先级设置
#include<iostream>
#include<queue>
using namespace std;
struct fruit{
string name;
int price;
// 建立最小堆
friend bool operator < (fruit f1, fruit f2){
return f1.price > f2.price;
}// “return f1.price > f2.price”,再排序中按价格从高到低排序,但是在优先队列中却是把价格低的放到队首
}f1, f2, f3;
int main(){
priority_queue<fruit> q;
f1.name = "桃子";
f1.price = 2;
f2.name = "梨子";
f2.price = 4;
f3.name = "苹果";
f3.price = 1;
q.push(f1);
q.push(f2);
q.push(f3);
cout << q.top().name << " " << q.top().price << endl; // 苹果 1
return 0;
}
在排序中,如果是“return f1.price > f2.price”,那么则是按价格从高到低排序,但是在优先队列中却是把价格低的放到队首。原因在于,优先队列本身默认的规则就是优先级高的放在队首,因此把小于号重载为大于号的功能时只是把这个规则反向了一下。如果读者无法理解,那么不妨记住,优先队列的这个函数与sort中的cmp函数的效果是相反的。
有没有办法跟sort中的cmp函数那样写在结构体外面呢?
自然是有办法的,只需把friend去掉,把小于号改成一对小括号,再把重载的函数写在结构体外面,同时将其用struct包装起来。
#include<iostream>
#include<queue>
using namespace std;
struct fruit{
string name;
int price;
}f1, f2, f3;
struct cmp{
bool operator() (fruit f1, fruit f2){
return f1.price > f2.price;
}
};
int main(){
priority_queue<fruit, vector<fruit>, cmp> q;
f1.name = "桃子";
f1.price = 2;
f2.name = "梨子";
f2.price = 4;
f3.name = "苹果";
f3.price = 1;
q.push(f1);
q.push(f2);
q.push(f3);
cout << q.top().name << " " << q.top().price << endl; // 苹果 1
return 0;
}