优先队列priority_queue的排序
默认排序(降序排序)
· 默认的priority_queue采用降序排序
priority_queue<int>pq;
pq.push(3);
pq.push(1);
pq.push(2);
while(!pq.empty()) {
printf("%2d",pq.top());
pq.pop();
}
输出 3 2 1
· priority_queue内类型为pair时,先比较pair.first
大小, pair.first
相等时比较pair.second
大小
priority_queue<pair<int,int>>pq;
pq.push({1,2});
pq.push({2,1});
pq.push({3,4});
pq.push({1,4});
while(!pq.empty()) {
printf("%d %d\n",pq.top().first,pq.top().second);
pq.pop();
}
输出
3 4
2 1
1 4
1 2
升序排序
· 如果想要用升序排列怎么办?先看一下优先队列的定义
priority_queue<Type, Container, Functional>
其中Type 就是数据类型,Container 就是容器类型(Container必须是用数组实现的容器,比如vector,deque等等,但不能用 list。STL里面默认用的是vector),Functional 就是比较的方式,当需要用自定义的数据类型时才需要传入这三个参数,使用基本数据类型时,只需要传入数据类型,默认是大顶堆。
如果传入的是int类型,我们可以用👇定义一个升序优先队列
priority_queue <int,vector<int>,greater<int>> pq;
如果要定义一个降序优先队列(等同于默认的不写Container, Functional的方式),可以使用这种方法:
priority_queue <int,vector<int>,less<int>> pq;
其中greater
和less
是std
实现的两个仿函数
自定义比较方法
如果不想用greater
和less
,可以使用自定义的比较方法:
auto comp = []( int a, int b ) { return a > b; };
priority_queue< int , vector<int>, decltype( comp )> pq( comp );
问题来了,为什么初始化pq
的时候还要传comp
进去?
按照我们熟悉的sort
函数的经验,sort
使用lambda表达式定制排序时,可以这样写:
sort (vec.begin(), vec.end(), [](int a, int b) {return a < b;});
比着葫芦画瓢,把priority_queue
写成👇却不行。
priority_queue< int , vector<int>, [](int a, int b) {return a < b;}> pq;
为什么会出现这种情况,这就需要看一下priority_queue
的构造函数:
explicit priority_queue( const Compare& compare = Compare(),
const Container& cont = Container() );
可以看到,如果我们构造时,不指定特定的compare
对象,那么就用typename Compare
的默认构造函数构造一个,然而lambda表达式的匿名类型是没有默认构造函数的,
所以想要正确初始化这个优先队列,还得在构造函数里再把lambda表达式本身传进去。