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

原文地址:https://www.cnblogs.com/grj001/p/12224445.html