关于最小堆以及priority_queue

来源:互联网 发布:linux统计ls-l行数 编辑:程序博客网 时间:2024/06/07 14:20

今天刷题用到了最小堆,想直接用STL库去实现,无奈用得少,不太熟练,现在把刚学到的列在这儿。

最小堆(最大堆)可以有两种实现方法:vector和priority_queue,不过两种的底层实现是一样的。

这里主要是针对自定义的数据结构。

1. 两种方法可以都重载<运算符来确定优先级(注意:必须是“<”操作符)

直接上代码:

#include<iostream>#include<queue>using namespace std;struct edge{int u,v,w;edge():u(0),v(0),w(0) {}edge(int _u,int _v, int _w):u(_u),v(_v),w(_w) {}friend bool operator<(edge a,edge b) {return a.w>b.w;}};int main(){priority_queue<edge> q;q.push(edge(1,2,300));q.push(edge(3,2,20));q.push(edge(1,3,65));q.push(edge(1,2,22));q.push(edge(1,3,40));q.push(edge(1,2,100));while (!q.empty()){edge e=q.top();q.pop();cout<<e.u<<" "<<e.v<<" "<<e.w<<endl;}cout<<endl;system("pause");return 0;}

还有用vector的

#include<iostream>#include<vector>#include<functional>#include<algorithm>using namespace std;struct edge{int u,v,w;edge():u(0),v(0),w(0) {}edge(int _u,int _v, int _w):u(_u),v(_v),w(_w) {}friend bool operator<(edge a,edge b) {return a.w>b.w;}};int main(){vector<edge> vec;vec.push_back(edge(1,2,300));vec.push_back(edge(3,2,20));vec.push_back(edge(1,3,65));vec.push_back(edge(1,2,22));vec.push_back(edge(1,2,40));vec.push_back(edge(1,2,100));make_heap(vec.begin(),vec.end());sort_heap(vec.begin(),vec.end());while (!vec.empty()){cout<<vec[0].u<<" "<<vec[0].v<<" "<<vec[0].w<<endl;pop_heap(vec.begin(),vec.end());vec.pop_back();}system("pause");return 0;}




2. 自定义,两者不一样,priority_queue得定义一个类,而vector传入一个函数指针就行

对于priority_queue:

#include<iostream>#include<queue>using namespace std;struct edge{int u,v,w;edge():u(0),v(0),w(0) {}edge(int _u,int _v, int _w):u(_u),v(_v),w(_w) {}/*friend bool operator<(edge a,edge b) {return a.w>b.w;}*/};struct cmp{bool operator()(const edge &a,const edge &b){return a.w < b.w;}};int main(){priority_queue<edge,vector<edge>,cmp> q;//priority_queue<edge> q;q.push(edge(1,2,300));q.push(edge(3,2,20));q.push(edge(1,3,65));q.push(edge(1,2,22));q.push(edge(1,3,40));q.push(edge(1,2,100));while (!q.empty()){edge e=q.top();q.pop();cout<<e.u<<" "<<e.v<<" "<<e.w<<endl;}cout<<endl;system("pause");return 0;}
对于vector,有

#include<iostream>#include<vector>#include<functional>#include<algorithm>using namespace std;struct edge{int u,v,w;edge():u(0),v(0),w(0) {}edge(int _u,int _v, int _w):u(_u),v(_v),w(_w) {}};bool cmp(const edge &a,const edge &b){return a.w > b.w;}int main(){vector<edge> vec;vec.push_back(edge(1,2,300));vec.push_back(edge(3,2,20));vec.push_back(edge(1,3,65));vec.push_back(edge(1,2,22));vec.push_back(edge(1,2,40));vec.push_back(edge(1,2,100));make_heap(vec.begin(),vec.end(),cmp);//sort_heap(vec.begin(),vec.end(),cmp);while (!vec.empty()){cout<<vec[0].u<<" "<<vec[0].v<<" "<<vec[0].w<<endl;pop_heap(vec.begin(),vec.end(),cmp);vec.pop_back();}system("pause");return 0;}

注意:1. queue和priority_queue没有begin和end函数。

           2. 很长时间没有理解比较函数的工作原理(即大于号小于号到底怎么选,到底a>b是最大堆还是最小堆),看了网上的博客,可以这样记忆比较函数的意义:a,b是数据结构的前后两个元素,如果返回true,则两个元素需要交换位置,反之则不需要。因此,我上面贴的代码里面a.w>b.w是生成的最小堆。

          3. priority_queue默认用的比较方式是less<T>(),产生最大堆,反之,仿函数为greater<T>(),产生最小堆。

3 0
原创粉丝点击