首先我们需要知道优先队列priority_queue分为大根(顶)堆和小根(顶)堆(很久前看到一个博主说大顶堆是小根堆......让我把这个搞混了好久,以至于看优先队列的时候有些博主说默认大根堆,有些说默认大顶堆让我搞不明白了)
然后
priority_queue<int> q
这是默认写法,也可以写成
priority_queue <int,vector<int>,less<int> >q
这是大根堆,意思是输出的时候从根输出,而根是大的,所以输出是从大到小的。
而
priority_queue<int,vector<int>,greater<int>> q
则是小根堆,要记住带上greater的是小,反过来的。
然后就是优先队列的内部排序了,我们将它分为两类。
一类是以pair和int等常见的数据类型(可以默认,也可以自己写比较方法)
一类是自己定义的结构体(因为pair有first,second关系,而结构体没有先后关系,所以必须自己写比较方法,不能默认,而结构体的比较方法又有内部重载大于小于号和外部cmp两种方式)
一.pair和int等基本数据类型
1.对pair排序,
(1)如果自己不写cmp的话,默认先以first排序再根据second
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int main()
{
priority_queue<pair<int, int> > a;
pair<int, int> b(1, 2);
pair<int, int> c(1, 3);
pair<int, int> d(2, 5);
a.push(d);
a.push(c);
a.push(b);
while (!a.empty())
{
cout << a.top().first << ' ' << a.top().second << '\n';
a.pop();
}
}
输出(这是大根堆)
2 5
1 3
1 2
(2)自定义cmp
cmp必须为类,然后重载内部的比较函数,比较函数的内部与通常的cmp写法一样
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
struct cmp {
bool operator()(const pair<int, int>& a, const pair<int, int>& b) const {
if (a.first != b.first) return a.first > b.first;
else return a.second < b.second; //根据first升序,second降序
}
};
int main()
{
priority_queue<pair<int, int>,vector<pair<int,int> >,cmp > a;
pair<int, int> b(1, 2);
pair<int, int> c(1, 3);
pair<int, int> d(2, 5);
a.push(d);
a.push(c);
a.push(b);
while (!a.empty())
{
cout << a.top().first << ' ' << a.top().second << '\n';
a.pop();
}
}
输出
1 3
1 2
2 5
2.对基本数据类型排序
几乎只要用到默认和greater这两个
二.对自定义结构体排序
(1).在结构体内部重载大于小于号,这个重载也有两种方法
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
struct node
{
int x;
int y;
/*friend bool operator > (const node& a, const node& b) //法一,这里是小根堆,有greater,要重载大于号
{
if (a.x != b.x)
{
return a.x > b.x;
}
else
{
return a.y < b.y;
}
}*/
bool operator > ( const node& b) const //法二
{
if (x != b.x)
{
return x > b.x;
}
else
{
return y < b.y;
}
}
};
priority_queue<node,vector<node>,greater<node>>q;
signed main()
{
q.push({ 5,4 });
q.push({ 5,3 });
q.push({ 1,2 });
q.push({ 1,1 });
q.push({ 3,3 });
q.push({ 3,1 });
while (!q.empty())
{
node t = q.top();
q.pop();
cout << t.x << " " << t.y << endl;
}
}
(2)在外面写cmp,和pair的cmp长得一样
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
struct node
{
int x;
int y;
};
struct cmp {
//通常这里尽量加const和&这两个,当数据量比较庞大时,提高效率
bool operator () (const node& a, const node& b)
{
if (a.x != b.x)
{
return a.x > b.x;
}
else
{
return a.y < b.y;
}
}
};
priority_queue<node,vector<node>,cmp>q;
signed main()
{
q.push({ 5,4 });
q.push({ 5,3 });
q.push({ 1,2 });
q.push({ 1,1 });
q.push({ 3,3 });
q.push({ 3,1 });
while (!q.empty())
{
node t = q.top();
q.pop();
cout << t.x << " " << t.y << endl;
}
}