什么是优先队列
优先队列(priority_queue)是一种具有自动排序功能的队列。是一种STL数据结构。
优先队列的声明
首先要包含头文件和命名空间
#include<queue>
using namespace std;
优先队列名字中虽然含有队列,本质上是一种大小顶堆的队列形式,并不是真正的队列,。它的排序方式也和大小顶堆相同。
声明一个有限队列的基本格式是:
priority_queue<type>q;
但是直接定义出来的优先队列默认是从大到小排序的,如果想让它按照特定顺序排列,就需要我们自定义一个排序规则。
对于int型数据,可以用内置的排序模板:
priority_queue<int, vector<int>, less<int>> pq; // 最大堆,从大到小
priority_queue<int, vector<int>, greater<int>> pq; // 最小堆,从小到大
因为优先队列是根据优先级存放数据的,假设是最大堆,存放的时候会进行比较,如果要存放的数据比当前的堆顶值更小,那么它的优先级更低,反之,优先级更高;最小堆的话完全反过来。所以对于最小堆,如果要存放的数据比当前top的值大, 那么它的优先级更低,这样的排序与sort排序给人的感觉是相反的,也是容易让人感到困惑的一点。
对于非int型的数据,需要自定义排序规则:
方法一(结构体内重载比大小符号):
struct node
{
int x,y;
bool operator < (const node & a) const
{
return x<a.x;
}
};
这个node结构体有两个成员,x和y,它的小于规则是x小者小。
假设上面这个程序插入(10,100),(12,60),(14,40),(6,20),(8,20)这五个node。
它的输出就会是:
(14,40) (12,60) (10,100) (8,20) (6,80)
可以看到小于并不是指的值,而是表示优先级,利用优先级排序和sort正好相反。
方法二(重载()符号):
struct cmp1{
bool operator()(int x,int y)
{
return x>y;
}
};
// priority_queue自定义函数的比较与sort正好是相反的
// 也就是说,如果你是把大于号作为第一关键字的比较方式,那么堆顶的元素就是第一关键字最小的
priority_queue<int,vector<int>,cmp1>q2;
方法三(友元函数重载<运算符):
struct Status{
int val;
ListNode* node;
friend bool operator<(Status a, Status b) // 形参可以加上const关键字和&,保证安全性,提高效率
{
return a.val > b.val;
}
};
priority_queue<Status> pq;
重载()和重载<是两种不同的思路,前者是修改优先队列设置优先级的方式,后者是改变优先队列存放的数据类型,可以根据需要选择合适的自定义排序方法。
优先队列的相关操作
和队列是一样的
q.size();//返回q里元素个数
q.empty();//返回q是否为空,空则返回1,否则返回0
q.push(k);//在q的末尾插入k
q.pop();//删掉q的第一个元素
q.top();//返回q的第一个元素
优先队列例题
leetcode347力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台