zoukankan      html  css  js  c++  java
  • ACM向:关于优先队列priority_queue自定义比较函数用法整理

    版权声明:(╯3╰) 转载请注明: https://blog.csdn.net/bat67/article/details/77585312

    关于优先队列priority_queue自定义比较函数用法整理

    原来上不了网,写在word里了,代码什么的直接贴过来了,有空整理成高亮的形式。

    0.0、首先注意一点,priority_queue没有front()方法,和一般的queue不一样,与这个方法对应的是top()

    0.1默认的:

    它的模板声明带有三个参数,priority_queue<Type, Container, Functional>
    Type 为数据类型,

    Container 为保存数据的容器,

    Functional 为元素比较方式。


    Container 必须是用数组实现的容器,比如 vector, deque 但不能用 list.
    STL里面默认用的是 vector. 比较方式默认用 operator< ,

    所以如果你把后面俩个参数缺省的话,

    优先队列就是大顶堆,队头元素最大。

    1、重载bool operator<,写在结构体外面

    
    #include<queue>
    #include<iostream>
    
    using namespacestd;
    
    struct node{
        int x, y;
        node(int x=0, int y=0):x(x),y(y){}
    };
    
    
    bool operator < (node a, node b){
        if(a.x > b.x) return 1;
        else if(a.x == b.x)
        if(a.y >= b.y) return 1;
    return 0;
    
    
    }
    
    
    int main() {
    
        priority_queue<node> pq;
        pq.push(node(1,2)); pq.push(node(2,2));
        pq.push(node(2,3)); pq.push(node(3,3));
        pq.push(node(3,4)); pq.push(node(4,4));
        pq.push(node(4,5)); pq.push(node(5,5));
        while(!pq.empty()) {
            cout<<pq.top().x<<pq.top().y<<endl;
            pq.pop();
        }
    
    
    return 0;
    
    
    }

    或者写成 const node &a

    
    bool operator < (const node &a,const node &b){
        if(a.x > b.x) return 1;
        else if(a.x == b.x)
        if(a.y >= b.y) return 1;
        return 0;
    }

    或者写成 const node a

    
    bool operator < (const node a,const node b){
        if(a.x > b.x) return 1;
        else if(a.x == b.x)
        if(a.y >= b.y) return 1;
        return 0;
    }

    但是这样不行 node &a

    
     
    1. bool operator < (node &a, node &b)

    2.  
    3. {

    4.  
    5. if(a.x > b.x) return 1;

    6.  
    7. else if(a.x == b.x)

    8.  
    9. if(a.y >= b.y) return 1;

    10.  
    11. return 0;

    12.  
    13. }

    2、重载bool operator<,写在结构体里面

    要是直接写在里面就只需要一个参数,但是后面必须加const修饰,否则报错,如:bool operator < (const node &b) const

    同样const node &a和node a都可以,但node &a不可以

    
     
    1. #include<queue>

    2.  
    3. #include<iostream>

    4.  
    5. using namespacestd;

    6.  
    7. struct node

    8.  
    9. {

    10.  
    11. int x, y;

    12.  
    13. node(int x=0, int y=0):x(x),y(y){}

    14.  
    15. bool operator<(const node &b) const

    16.  
    17. {

    18.  
    19. if(x > b.x) return 1;

    20.  
    21. else if(x == b.x)

    22.  
    23. if(y >= b.y) return 1;

    24.  
    25. return 0;

    26.  
    27. }

    28.  
    29. };

    30.  
    31.  
    32. int main()

    33.  
    34. {

    35.  
    36. priority_queue<node> pq;

    37.  
    38. pq.push(node(1,2)); pq.push(node(2,2));

    39.  
    40. pq.push(node(2,3)); pq.push(node(3,3));

    41.  
    42. pq.push(node(3,4)); pq.push(node(4,4));

    43.  
    44. pq.push(node(4,5)); pq.push(node(5,5));

    45.  
    46. while(!pq.empty())

    47.  
    48. {

    49.  
    50. cout<<pq.top().x<<pq.top().y<<endl;

    51.  
    52. pq.pop();

    53.  
    54. }

    55.  
    56. return 0;

    57.  
    58. }

    友元必须要写在里面,且是两个参数,同样node &a不可以,const node &a和node a都可以,但是无需const在函数最后修饰,否则报错

    
     
    1. struct node

    2.  
    3. {

    4.  
    5. int x, y;

    6.  
    7. node(int x=0, int y=0):x(x),y(y){}

    8.  
    9. friend bool operator<(const node&a, const node &b)

    10.  
    11. {

    12.  
    13. if(a.x > b.x) return 1;

    14.  
    15. else if(a.x == b.x)

    16.  
    17. if(a.y >= b.y) return 1;

    18.  
    19. return 0;

    20.  
    21. }

    22.  
    23. };

    3、可以自定义一个比较类,Compare

    priority_queue中的三个参数,后两个可以省去,因为有默认参数,不过如果,有第三个参数的话,必定要写第二个参数。

    而且这个是一个类,这个类里重载operator(),和自定义sort排序不同,sort只需bool cmp(……)(当然sort也可以弄一个比较类,再重载operator()),若是priority_queue中写为sort的cmp形式则报错,如:bool cmp1(const node &a, const node&b)//报错!

    
     
    1. #include <queue>

    2.  
    3. #include <iostream>

    4.  
    5. using namespace std;

    6.  
    7. struct node

    8.  
    9. {

    10.  
    11. int x, y;

    12.  
    13. node(intx=0, int y=0):x(x),y(y){}

    14.  
    15. };

    16.  
    17. struct cmp

    18.  
    19. {

    20.  
    21. booloperator()(const node &a, const node &b)

    22.  
    23. {

    24.  
    25. if(a.x> b.x) return 1;

    26.  
    27. elseif(a.x == b.x)

    28.  
    29. if(a.y>= b.y) return 1;

    30.  
    31. return0;

    32.  
    33. }

    34.  
    35. };

    36.  
    37. int main()

    38.  
    39. {

    40.  
    41. priority_queue<node,vector<node>, cmp> pq; //注意这里的写法

    42.  
    43. pq.push(node(1,2)); pq.push(node(2,2));

    44.  
    45. pq.push(node(2,3)); pq.push(node(3,3));

    46.  
    47. pq.push(node(3,4)); pq.push(node(4,4));

    48.  
    49. pq.push(node(4,5)); pq.push(node(5,5));

    50.  
    51. while(!pq.empty())

    52.  
    53. {

    54.  
    55. cout<<pq.top().x<<pq.top().y<<endl;

    56.  
    57. pq.pop();

    58.  
    59. }

    60.  
    61. return0;

    62.  
    63. }

    值得注意的是,这个比较类里node&a,const node &a和node a都可以了,重载bool operator() 最后加const修饰也可以。

    最后忘写了,上面所有程序排序结果都为

    12

    22

    23

    33

    34

    44

    45

    55

    请按任意键继续. . .

    补充:STL中sort、priority_queue、map、set的自定义比较函数

    STL中,sort的默认排序为less,也就是说从小到大排序;priority_queue默认是less,也就说大顶堆;map默认是less,也就说用迭代器迭代的时候默认是小的排在前面;set默认是less,也就是说用迭代器迭代的时候是从小到大排序的。

    1、sort

    
     #include <stdio.h>
    
    
    #include <algorithm>
    #include <functional>
    
    using namespacestd;
    bool comp(constint& a, const int& b ){
    return a < b ; //从小到大
    }
    
    struct cmp{
    bool operator()( const int& a , constint& b ) const{
    return a < b ; //从小到大
    }
    };
    
    int main(){
    int array[] = {1 ,5 ,4, 10, 3, 6 } ;
    sort( array , array+6 ) ; //以默认的less<int>()排序
    sort( array , array+6 ,greater<int>() ) ; //从大到小排序
    sort( array , array+6 , comp ) ;
    sort( array , array+6 , cmp() ) ;
    for(int i=0;i<6;++i) printf("%d ",array[i]);printf("\n");
    return 0 ;
    }

    2、priority_queue

    
    #include<stdio.h>
    #include<queue>
    
    using namespacestd ;
    
    struct cmp{
    bool operator()( const int& a , constint& b )const{
    return a < b ; //大顶堆
    }
    };
    
    
    struct Node{
    int x, y ;
    Node(int _x, int _y ):x(_x),y(_y){}
    bool operator <(const Node&n1)const{
    if( x < n1.x ) return true ; //按照x为第一关键字由大到小排序
    else if( x == n1.x ) return y < n1.y ; //y为第二关键字由大到小排序
    else return false ;
    }
    };
    
    int main(){
    //priority_queue<int> q ; //优先队列默认是less,大顶堆;
    //priority_queue<int,vector<int>,cmp> q ;
    priority_queue< Node > q ;
    
    
    
    for(int i=0;i<10;i++) q.push( Node( rand() , rand() ) );
    while( !q.empty() ){
    printf("%d %d\n",q.top().x ,q.top().y ) ;
    q.pop() ;
    }
    return 0 ;
    }

    3、map

    
    #include<stdio.h>
    #include<map>
    
    using namespacestd;
    
    struct cmp{
    bool operator()( const int& a, constint& b ) const{
    return a < b ; //从小到大;
    }
    };
    
    int main(){
    //map<int, int,greater<int> >mp ; //从大到小
    map<int , int ,cmp> mp ;
    for(int i=0;i<10;++i) mp.insert( map<int,int,cmp>::value_type(rand() ,i) ) ;
    map<int, int, cmp >::iterator it =mp.begin() ;
    for( ;it!=mp.end() ;it++) printf("%d %d\n",(*it).first ,(*it).second );
    return 0 ;
    }

    4、set

    
    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<set>
    
    using namespacestd;
    
    struct cmp{
    bool operator()( const int& a , constint& b )const{
    return a < b ; //从小到大
    }
    };
    
    int main(){
    //set<int > s ;
    set<int,cmp> s ;
    for(int i=0;i<10;i++) s.insert( rand() ) ;
    set<int,cmp>::iterator it = s.begin();
    for( ; it!=s.end();it++)
    printf("%d\n",*it);
    return 0 ;
    }

    priority_queue 优先级队列是一个拥有权值概念的单向队列queue,

    在这个队列中,所有元素是按优先级排列的

    (也可以认为queue是个按进入队列的先后做为优先级的优先级队列——先进入队列的元素优先权要高于后进入队列的元素)。

    在计算机操作系统中,优先级队列的使用是相当频繁的,进线程调度都会用到。

    在STL的具体实现中,priority_queue也是以别的容器作为底部结构,再根据堆的处理规则来调整元素之间的位置。

    下面给出priority_queue的函数列表和VS2008中priority_queue的源代码,本文中与heap有关的函数参见《STL系列之四 heap 堆》。

    priority_queue函数列表

    函数

    描述      by MoreWindows( http://blog.csdn.net/MoreWindows )

    构造析构

    priority_queue <Elem> c

     创建一个空的queue 。
    注:priority_queue构造函数有7个版本,请查阅MSDN

    数据访问与增减

    c.top()

    返回队列头部数据

    c.push(elem)

    在队列尾部增加elem数据

     c.pop()

    队列头部数据出队

    其它操作

    c.empty()

    判断队列是否为空

    c.size()

    返回队列中数据的个数

    可以看出priority_queue的函数列表与栈stack的函数列表是相同的。

    VS2008中priority_queue 优先级队列的源代码

    友情提示:初次阅读时请注意其实现思想,不要在细节上浪费过多的时间

    
     
    1. //VS2008中 priority_queue的定义 MoreWindows整理( http://blog.csdn.net/MoreWindows )

    2.  
    3. template<class_Ty, class _Container = vector<_Ty>, class _Pr = less<typename_Container::value_type> > //默认以vector为容器的

    4.  
    5. class priority_queue

    6.  
    7. { // priority queue implemented with a_Container

    8.  
    9. public:

    10.  
    11. typedef _Container container_type;

    12.  
    13. typedef typename _Container::value_typevalue_type;

    14.  
    15. typedef typename _Container::size_typesize_type;

    16.  
    17. typedef typename _Container::referencereference;

    18.  
    19. typedef typename_Container::const_reference const_reference;

    20.  
    21.  
    22. priority_queue() : c(), comp()

    23.  
    24. { // construct with empty container, default comparator

    25.  
    26. }

    27.  
    28.  
    29. explicit priority_queue(const _Pr&_Pred) : c(), comp(_Pred)

    30.  
    31. { // construct with empty container, specified comparator

    32.  
    33. }

    34.  
    35.  
    36. priority_queue(const _Pr& _Pred, const_Container& _Cont) : c(_Cont), comp(_Pred)

    37.  
    38. { // construct by copying specified container, comparator

    39.  
    40. make_heap(c.begin(), c.end(), comp); //参见《STL系列之四 heap 堆的相关函数》

    41.  
    42. }

    43.  
    44.  
    45. template<class _Iter>

    46.  
    47. priority_queue(_Iter _First, _Iter _Last) :c(_First, _Last), comp()

    48.  
    49. { // construct by copying [_First, _Last), default comparator

    50.  
    51. make_heap(c.begin(), c.end(),comp);

    52.  
    53. }

    54.  
    55.  
    56. template<class _Iter>

    57.  
    58. priority_queue(_Iter _First, _Iter _Last,const _Pr& _Pred) : c(_First, _Last), comp(_Pred)

    59.  
    60. { // construct by copying [_First, _Last), specified comparator

    61.  
    62. make_heap(c.begin(), c.end(),comp);

    63.  
    64. }

    65.  
    66.  
    67. template<class _Iter>

    68.  
    69. priority_queue(_Iter _First, _Iter _Last,const _Pr& _Pred, const _Container& _Cont) : c(_Cont), comp(_Pred)

    70.  
    71. { // construct by copying [_First, _Last), container, and comparator

    72.  
    73. c.insert(c.end(), _First, _Last);

    74.  
    75. make_heap(c.begin(), c.end(),comp);

    76.  
    77. }

    78.  
    79.  
    80. bool empty() const

    81.  
    82. { // test if queue is empty

    83.  
    84. return (c.empty());

    85.  
    86. }

    87.  
    88.  
    89. size_type size() const

    90.  
    91. { //return length of queue

    92.  
    93. return (c.size());

    94.  
    95. }

    96.  
    97.  
    98. const_reference top() const

    99.  
    100. { // return highest-priority element

    101.  
    102. return (c.front());

    103.  
    104. }

    105.  
    106.  
    107. reference top()

    108.  
    109. { // return mutable highest-priority element (retained)

    110.  
    111. return (c.front());

    112.  
    113. }

    114.  
    115.  
    116. void push(const value_type& _Pred)

    117.  
    118. { // insert value in priority order

    119.  
    120. c.push_back(_Pred);

    121.  
    122. push_heap(c.begin(), c.end(),comp);

    123.  
    124. }

    125.  
    126.  
    127. void pop()

    128.  
    129. { // erase highest-priority element

    130.  
    131. pop_heap(c.begin(), c.end(),comp);

    132.  
    133. c.pop_back();

    134.  
    135. }

    136.  
    137.  
    138. protected:

    139.  
    140. _Container c; // the underlying container

    141.  
    142. _Pr comp; // the comparator functor

    143.  
    144. };

  • 相关阅读:
    洛谷 P3868 [TJOI2009]猜数字
    洛谷 P2661 信息传递
    hdu 5418 Victor and World
    洛谷 P5024 保卫王国
    洛谷 P2470 [SCOI2007]压缩
    双栈排序 2008年NOIP全国联赛提高组(二分图染色)
    理想的正方形 HAOI2007(二维RMQ)
    10.23NOIP模拟题
    疫情控制 2012年NOIP全国联赛提高组(二分答案+贪心)
    图论模板
  • 原文地址:https://www.cnblogs.com/grj001/p/12224446.html
Copyright © 2011-2022 走看看