priority_queue 对于基本类型的使用方法相对简单。他的模板声明带有三个参数, Type 为数据类型, Container 为保存数据的容器,Functional 为元素比较方式。Container 必须是用数组实现的容器,比如 vector, deque 但不能用 list.STL里面容器默认用的是 vector. 比较方式默认用 operator< , 所以如果你把后面俩个参数 缺省的话,优先队列就是大顶堆,队头元素最大。
实例
#include <queue> using namespace std; int main(){ priority_queue<int,vector<int>,less<int> >q1;//使用priority_queue<int> q1;一样,都是大根堆,没错,就是大根堆 for(int i=0;i<10;i++) q1.push(i); while(!q1.empty()){ cout<<q1.top()<< endl; q1.pop(); } return 0; }如果要用到小顶堆,则一般要把模板的三个参数都带进去。
#include <iostream> #include <queue> using namespace std; int main(){ priority_queue<int,vector<int>,greater<int> >q; for(int i=0;i<10;i++) q.push(i); while(!q.empty()){ cout<<q.top()<< endl; q.pop(); } return 0; }
两种是等价的
1:
#include <iostream> #include <queue> using namespace std; struct Node{ int x, y; bool operator<( const Node &b)const//为什么这么多const(只读)和&(引用)<span style="font-family: Arial, Helvetica, sans-serif;"> 该问题在下文,会提到</span>
{ if(x==b.x) return y>b.y; return x>b.x; }//定义为成员函数,只有当运算符左边为该结构体变量时,才起作用 }node; int main(){ priority_queue<Node>q; for(int i=0;i<10;i++){ node.x=i; node.y=10-i/2; q.push(node); } while(!q.empty()){ cout<<q.top().x <<' '<<q.top().y<<endl; q.pop(); } return 0; }
#include <iostream> #include <queue> using namespace std; struct Node{ int x, y; }node; bool operator<( Node a, Node b){ if(a.x==b.x) return a.y>b.y; return a.x>b.x; }//在结构体外面定义,为全局名字空间的成员,定义在外面,运算符左边的可以不是结构体变量,也就是说,此处前一个的Node 允许换为int
//同时,放在结构体外面,就不用放那些麻烦的const & int main(){ priority_queue<Node>q; for(int i=0;i<10;i++){ node.x=i; node.y=10-i/2; q.push(node); } while(!q.empty()){ cout<<q.top().x <<' '<<q.top().y<<endl; q.pop(); } return 0; }
注意:
以前一直有一个不明白的问题,对于sort来说,cmp函数只要是<,那么就是小于,然后升序;>就是从大到小
但是看很多其他的定义来说,就不是这个样子,和想象的相反
struct Node{ <span style="white-space:pre"> </span>int x, y; <span style="white-space:pre"> </span>bool operator<( const Node &b)const <span style="white-space:pre"> </span>{ <span style="white-space:pre"> </span>if(x==b.x) return y>b.y; <span style="white-space:pre"> </span>return x>b.x; <span style="white-space:pre"> </span>}//例如这里,这是上文优先队列的重载,意思是说按x为第一关键字,y为第二关键字,的小根堆,但是注意上面是operator <
//下面就成了x>b.x,不对啊?事实上,优先队列内部就是一个堆,里面的运算符均为<,即默认的运算符,但是我们把他赋予了>的意义,为什么要赋予>的意思n呢?因为,在priority_pueue内部,默认是大根堆,也就是说,如果根节点<span style="color:#ff0000;">小于</span>一个孩子的话,那么交换(<就是用在这里)我们把他要改为小根堆,那么就是如果根节点大,才交换,<的符号没变,只是代表了>而以。x呢就是运算符左边的,b.x自然就是右边的。
}node;差不多明白了
不过那些cosnt 和& 是干什么的
认识一些概念
1. 比如你定义一个函数void add(int a, int b),这里的a和b就是形参。
2. 当你进行函数调用的时候,add(1, 2),这里的1和2就是实参。
bool operator<( const Node &b)const { if(x==b.x) return y>b.y; return x>b.x; }
还有如果光是第一个const删了(&不动),也会报错
因为:如果使用引用类型的实参的唯一目的是为了避免大量的复制实参,而不对实参做修改,最好使用的形参类型为const 类型名&。这也就是为什么上面用const node &b,所以,一定要加上,第二个const就直接背过即可。
详见:http://blog.csdn.net/guiyinzhou/article/details/6298030 C++『const 引用 传参』『类成员函数』