版权声明:(╯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
-
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;
-
}
2、重载bool operator<,写在结构体里面
要是直接写在里面就只需要一个参数,但是后面必须加const修饰,否则报错,如:bool operator < (const node &b) const
同样const node &a和node a都可以,但node &a不可以
-
#include<queue>
-
#include<iostream>
-
using namespacestd;
-
struct node
-
{
-
int x, y;
-
node(int x=0, int y=0):x(x),y(y){}
-
bool operator<(const node &b) const
-
{
-
if(x > b.x) return 1;
-
else if(x == b.x)
-
if(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;
-
}
友元必须要写在里面,且是两个参数,同样node &a不可以,const node &a和node a都可以,但是无需const在函数最后修饰,否则报错
-
struct node
-
{
-
int x, y;
-
node(int x=0, int y=0):x(x),y(y){}
-
friend 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;
-
}
-
};
3、可以自定义一个比较类,Compare
priority_queue中的三个参数,后两个可以省去,因为有默认参数,不过如果,有第三个参数的话,必定要写第二个参数。
而且这个是一个类,这个类里重载operator(),和自定义sort排序不同,sort只需bool cmp(……)(当然sort也可以弄一个比较类,再重载operator()),若是priority_queue中写为sort的cmp形式则报错,如:bool cmp1(const node &a, const node&b)//报错!
-
#include <queue>
-
#include <iostream>
-
using namespace std;
-
struct node
-
{
-
int x, y;
-
node(intx=0, int y=0):x(x),y(y){}
-
};
-
struct cmp
-
{
-
booloperator()(const node &a, const node &b)
-
{
-
if(a.x> b.x) return 1;
-
elseif(a.x == b.x)
-
if(a.y>= b.y) return 1;
-
return0;
-
}
-
};
-
int main()
-
{
-
priority_queue<node,vector<node>, cmp> 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();
-
}
-
return0;
-
}
值得注意的是,这个比较类里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 。 |
数据访问与增减 |
|
c.top() |
返回队列头部数据 |
c.push(elem) |
在队列尾部增加elem数据 |
c.pop() |
队列头部数据出队 |
其它操作 |
|
c.empty() |
判断队列是否为空 |
c.size() |
返回队列中数据的个数 |
可以看出priority_queue的函数列表与栈stack的函数列表是相同的。
VS2008中priority_queue 优先级队列的源代码
友情提示:初次阅读时请注意其实现思想,不要在细节上浪费过多的时间
-
//VS2008中 priority_queue的定义 MoreWindows整理( http://blog.csdn.net/MoreWindows )
-
template<class_Ty, class _Container = vector<_Ty>, class _Pr = less<typename_Container::value_type> > //默认以vector为容器的
-
class priority_queue
-
{ // priority queue implemented with a_Container
-
public:
-
typedef _Container container_type;
-
typedef typename _Container::value_typevalue_type;
-
typedef typename _Container::size_typesize_type;
-
typedef typename _Container::referencereference;
-
typedef typename_Container::const_reference const_reference;
-
priority_queue() : c(), comp()
-
{ // construct with empty container, default comparator
-
}
-
explicit priority_queue(const _Pr&_Pred) : c(), comp(_Pred)
-
{ // construct with empty container, specified comparator
-
}
-
priority_queue(const _Pr& _Pred, const_Container& _Cont) : c(_Cont), comp(_Pred)
-
{ // construct by copying specified container, comparator
-
make_heap(c.begin(), c.end(), comp); //参见《STL系列之四 heap 堆的相关函数》
-
}
-
template<class _Iter>
-
priority_queue(_Iter _First, _Iter _Last) :c(_First, _Last), comp()
-
{ // construct by copying [_First, _Last), default comparator
-
make_heap(c.begin(), c.end(),comp);
-
}
-
template<class _Iter>
-
priority_queue(_Iter _First, _Iter _Last,const _Pr& _Pred) : c(_First, _Last), comp(_Pred)
-
{ // construct by copying [_First, _Last), specified comparator
-
make_heap(c.begin(), c.end(),comp);
-
}
-
template<class _Iter>
-
priority_queue(_Iter _First, _Iter _Last,const _Pr& _Pred, const _Container& _Cont) : c(_Cont), comp(_Pred)
-
{ // construct by copying [_First, _Last), container, and comparator
-
c.insert(c.end(), _First, _Last);
-
make_heap(c.begin(), c.end(),comp);
-
}
-
bool empty() const
-
{ // test if queue is empty
-
return (c.empty());
-
}
-
size_type size() const
-
{ //return length of queue
-
return (c.size());
-
}
-
const_reference top() const
-
{ // return highest-priority element
-
return (c.front());
-
}
-
reference top()
-
{ // return mutable highest-priority element (retained)
-
return (c.front());
-
}
-
void push(const value_type& _Pred)
-
{ // insert value in priority order
-
c.push_back(_Pred);
-
push_heap(c.begin(), c.end(),comp);
-
}
-
void pop()
-
{ // erase highest-priority element
-
pop_heap(c.begin(), c.end(),comp);
-
c.pop_back();
-
}
-
protected:
-
_Container c; // the underlying container
-
_Pr comp; // the comparator functor
-
};