给定N个节点和他们的权值,以他们为叶节点构造一条带权路径长度和最小的二叉树,该二叉树即为哈夫曼树
哈夫曼树的求法
- 将所有节点都放入集合K
- 若集合中的节点个数小于2,取出其中权值最小的两个,将父节点放入K
- 若集合K中只有一个节点,该节点即为构造出的哈夫曼树的根节点
所有构造得到的中间节点(即哈夫曼树上非叶子节点)的权值和即为该哈夫曼树的带权路径和
为了方便快捷的求得集合K中权值最小的两个元素,使用堆数据结构——–使用相应的标准模板”优先队列“
题目一:
典型的最简单的哈夫曼树的带权最小路径和
代码:
#inlcude<queue>
#include<stdlib.h>
using namespace std;
priority_queue<int, vector<int>,greater<int>> Q;
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
while(Q.empty()==false) Q.pop();
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
Q.push(x);
}
int ans = 0;
while(Q.size()>1)
{
int a = Q.top();
Q.pop();
int b = Q.top();
Q.pop();
ans+=(a+b);
Q.push(a+b);
}
printf("%d\n",ans);
}
return 0;
}
模板中的优先队列:
priority_queue<int> Q //默认建立的是大顶堆
priority_queue<int, vector<int>, greater<int>> Q //小顶堆
题目二:
搬水果—跟上一道题目一样