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. };

  • 相关阅读:
    HDU 6182 A Math Problem 水题
    HDU 6186 CS Course 位运算 思维
    HDU 6188 Duizi and Shunzi 贪心 思维
    HDU 2824 The Euler function 欧拉函数
    HDU 3037 Saving Beans 多重集合的结合 lucas定理
    HDU 3923 Invoker Polya定理
    FZU 2282 Wand 组合数学 错排公式
    HDU 1452 Happy 2004 数论
    HDU 5778 abs 数论
    欧拉回路【判断连通+度数为偶】
  • 原文地址:https://www.cnblogs.com/grj001/p/12224446.html
Copyright © 2011-2022 走看看