优先队列学习之哈弗曼树
转载自:http://www.cppblog.com/darren/archive/2009/06/09/87224.html
priority_queue 调用 STL里面的 make_heap(), pop_heap(), push_heap() 算法
实现,也算是堆的另外一种形式。
先写一个用 STL 里面堆算法实现的与真正的STL里面的 priority_queue 用法相
似的 priority_queue, 以加深对 priority_queue 的理解
#include <iostream> #include <algorithm> #include <vector> using namespace std; class priority_queue { private: vector<int> data; public: void push( int t ){ data.push_back(t); push_heap( data.begin(), data.end()); } void pop(){ pop_heap( data.begin(), data.end() ); data.pop_back(); } int top() { return data.front(); } int size() { return data.size(); } bool empty() { return data.empty(); } }; int main() { priority_queue test; test.push( 3 ); test.push( 5 ); test.push( 2 ); test.push( 4 ); while( !test.empty() ){ cout << test.top() << endl; test.pop(); } return 0; }
STL里面的 priority_queue 写法与此相似,只是增加了模板及相关的迭代器什么的。
priority_queue 对于基本类型的使用方法相对简单。
他的模板声明带有三个参数,priority_queue<Type, Container, Functional>
Type 为数据类型, Container 为保存数据的容器,Functional 为元素比较方式。
Container 必须是用数组实现的容器,比如 vector, deque 但不能用 list.
STL里面默认用的是 vector. 比较方式默认用 operator< , 所以如果你把后面俩个
参数缺省的话,优先队列就是大顶堆,队头元素最大。
看例子
#include <iostream> #include <queue> using namespace std; int main(){ priority_queue<int> q; for( int i= 0; i< 10; ++i ) q.push( rand() ); while( !q.empty() ){ cout << q.top() << endl; q.pop(); } getchar(); return 0; }
如果要用到小顶堆,则一般要把模板的三个参数都带进去。
STL里面定义了一个仿函数 greater<>,对于基本类型可以用这个仿函数声明小顶堆
例子:
#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( rand() ); while( !q.empty() ){ cout << q.top() << endl; q.pop(); } getchar(); return 0; }
对于自定义类型,则必须自己重载 operator< 或者自己写仿函数
先看看例子:
#include <iostream> #include <queue> using namespace std; struct Node{ int x, y; Node( int a= 0, int b= 0 ): x(a), y(b) {} }; bool operator<( Node a, Node b ){ if( a.x== b.x ) return a.y> b.y; return a.x> b.x; } int main(){ priority_queue<Node> q; for( int i= 0; i< 10; ++i ) q.push( Node( rand(), rand() ) ); while( !q.empty() ){ cout << q.top().x << ' ' << q.top().y << endl; q.pop(); } getchar(); return 0; }
自定义类型重载 operator< 后,声明对象时就可以只带一个模板参数。
但此时不能像基本类型这样声明
priority_queue<Node, vector<Node>, greater<Node> >;
原因是 greater<Node> 没有定义,如果想用这种方法定义
则可以按如下方式
例子:
#include <iostream> #include <queue> using namespace std; struct Node{ int x, y; Node( int a= 0, int b= 0 ): x(a), y(b) {} }; struct cmp{ bool operator() ( Node a, Node b ){ if( a.x== b.x ) return a.y> b.y; return a.x> b.x; } }; int main(){ priority_queue<Node, vector<Node>, cmp> q; for( int i= 0; i< 10; ++i ) q.push( Node( rand(), rand() ) ); while( !q.empty() ){ cout << q.top().x << ' ' << q.top().y << endl; q.pop(); } getchar(); return 0; }
--------------------------------------
如下转载自:http://blog.csdn.net/zhc_ac/article/details/47395399
题目描述
输入
输出
示例输入
3 1 2 9
示例输出
15
#include <iostream> #include <stdio.h> #include <string.h> #include <queue>//头文件 using namespace std; struct cmp//函数从小到大排序,因为默认的优先队列是从大到小排序 { bool operator ()(long long &a,long long &b) { return a>b; } }; int main() { priority_queue<long long ,vector<long long>,cmp>q;//优先队列定义方式 long long a; int n,i; while(scanf("%d",&n)!=EOF) { long long x=0,y=0; long long ans = 0,sum = 0; for(i=0;i<n;i++) { scanf("%lld",&a); q.push(a);//把a加入到优先队列q中 } while(!q.empty())//当队列里还有数存在时 { x = q.top();//从队列中取出 q.pop();//把队列中的第一个字符删除 if(!q.empty()) { y = q.top(); q.pop(); ans = x+y; sum = sum + ans; q.push(ans); } } printf("%lld\n",sum); } return 0; }