Loading

优先队列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;

其中greaterlessstd实现的两个仿函数
 

自定义比较方法

如果不想用greaterless,可以使用自定义的比较方法:

  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表达式本身传进去。

posted @ 2021-11-29 23:28  柴承训  阅读(977)  评论(0编辑  收藏  举报