C++--优先队列备忘
2014-11-30 19:22:52
总结:优先队列学了已经很久,有时候容易忘,写个备忘吧。
先转一下经典blog:http://www.cppblog.com/shyli/archive/2007/04/06/21366.html
在优先队列中,优先级高的元素先出队列。
标准库默认使用元素类型的<操作符来确定它们之间的优先级关系。
优先队列的第一种用法,也是最常用的用法:
1 priority_queue<int> qi;
通过<操作符可知在整数中元素大的优先级高。
故示例1中输出结果为:9 6 5 3 2
第二种方法:
在示例1中,如果我们要把元素从小到大输出怎么办呢?
这时我们可以传入一个比较函数,使用functional.h函数对象作为比较函数。
1 priority_queue<int, vector<int>, greater<int> >qi2;
其中
第二个参数为容器类型。
第二个参数为比较函数。
故示例2中输出结果为:2 3 5 6 9
第三种方法:
自定义优先级。
1 struct node 2 { 3 friend bool operator< (node n1, node n2) 4 { 5 return n1.priority < n2.priority; 6 } 7 int priority; 8 int value; 9 };
在该结构中,value为值,priority为优先级。
通过自定义operator<操作符来比较元素中的优先级。
在示例3中输出结果为:
优先级 值
9 5
8 2
6 1
2 3
1 4
但如果结构定义如下:
struct node { friend bool operator> (node n1, node n2) { return n1.priority > n2.priority; } int priority; int value; };
则会编译不过(G++编译器)
因为标准库默认使用元素类型的<操作符来确定它们之间的优先级关系。
而且自定义类型的<操作符与>操作符并无直接联系,故会编译不过。
第四种方法:
重载 () 运算符。
struct cmp{ bool operator ()(pii a,pii b){ return a.first > b.first; } }; priority_queue<pii,vector<pii >,cmp> PQ;
好了,总结下自己的理解,由于不重载函数的话系统优先队列默认使用最大堆,所以重载的小于号我理解为谁的深度更深(谁越远离根),如 return a < b;的含义是a小于b时,a更远离根,构造了最大堆;同样地return a > b;含义是a大于b时,a更远离根,构造了最小堆。
例:最小堆(1)
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <iostream> 11 #include <algorithm> 12 using namespace std; 13 14 struct node{ 15 int v; 16 friend bool operator < (node a,node b){ 17 return a.v > b.v; 18 } 19 }x[5]; 20 21 int main(){ 22 for(int i = 0; i < 5; ++i) 23 x[i].v = i; 24 priority_queue<node> Q; 25 for(int i = 0; i < 5; ++i) 26 Q.push(x[i]); 27 while(!Q.empty()){ 28 node t = Q.top(); 29 printf("%d\n",t.v); 30 Q.pop(); 31 } 32 return 0; 33 }
最小堆(2)
1 int main(){ 2 int x[5] = {0,1,2,3,4}; 3 priority_queue<int,vector<int>,greater<int> > Q; 4 for(int i = 0; i < 5; ++i) 5 Q.push(x[i]); 6 while(!Q.empty()){ 7 printf("%d\n",Q.top()); 8 Q.pop(); 9 } 10 return 0; 11 }

浙公网安备 33010602011771号