priority_queue又被称为优先队列,底层用堆实现队首元素一定是队内元素中优先级最高的,
当然可以在任意时刻在堆中添加元素,优先队列会随时进行调整结构,使得每次出队的元素的优先级最大
这里的优先级是规定出来的,可以从小到大也可以从大到小
要使用优先队列要先加入头文件并且定义方法与其他容器基本相同
#include
using namespace std;
priority_queue< 定义类型 > name;
和队列不一样的是优先队列没有front()和back()函数,只能通过top()来访问队首元素其他地方也会叫它堆顶元素,实例:
#include
#include
using namespace std;
int main()
{
priority_queue<int> q;
q.push(3);
q.push(1);
q.push(4);
cout<<q.top()<<endl;
return 0;
}
//结果为 4
push(x)是将x入队,时间复杂度为O(logN),N为容器内元素个数。
top()可以获得队首元素时间复杂度为O(logN)
pop()将队首元素出队,时间复杂度为(logN)
#include
#include
using namespace std;
int main()
{
priority_queue<int> q;
q.push(3);
q.push(1);
q.push(4);
cout<<q.top()<<endl;
q.pop();
cout<<q.top()<<endl;
return 0;
}
输出 4 3
检测队列是否非空与queue相同
时间复杂度为O(1)
空 -> 真
非空 -> 假
返回优先队列的元素个数时间复杂度为O(1)
如何定义队列内优先级是运用优先级的关键
此处的类型就是,int,double,char…可以直接被使用的数据类型,一般来说是数字大的优先级高,char则是按字典序最大的,对基本定义类型来说,这两种是等价的
priority_queue<int> q;
priority_queue<int,vector<int>,less<int> >
可以发现第二种定义多了两个参数,第二个参数vector是承载堆的容器,而第三个参数less是表示数字大的优先级大,而greater是指数字越小优先级越大
可以做一个实例
#include
#include
using namespace std;
int main()
{
priority_queue<int,vector<int>,greater<int> > q;
q.push(3);
q.push(1);
q.push(4);
cout<<q.top()<<endl;
return 0;
}
//结果为 1
先建立一个成绩单的结构体
struct student
{
string name;
int score;
};
现在希望可以按学生分数从高到低排名,需要重载小于号(<),重载就是对已有的运算符进行重新定义,先写下来:
struct student
{
string name;
int score;
friend bool operator < (student s1,student s2){
return s1.score < s2.score;
}
};
student结构体中加入了一个函数,其中friend为友元,后面的bool operator < (student s1,student s2)是对运算符“<”(重载大于号会编译错误,因为数学上来说之需要重载小于号)
函数内部为return s1.score < s2.score,所以说重载后小于号还是小于号的作用,此时就可以直接定义student的结构体内部就是分数高的学生优先级高,如果要确定分数低的优先级高如下所示:
struct student
{
string name;
int score;
friend bool operator < (student s1,student s2){
return s1.score > s2.score;
}
};
最后如果出现了结构体内数据较为庞大,建议使用引用来提高效率,只需要加上const 和&,例如
struct student
{
string name;
int score;
friend bool operator < (const student &s1,const student &s2){
return s1.score > s2.score;
}
};
可以解决一些贪心问题,也可以对dijkstra算法进行优化