今天刷题用到了最小堆,想直接用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>(),产生最小堆。