C 数据结构之哈夫曼树

3.哈夫曼树,第一行输入一个数n,表示叶节点的个数。需要用这些叶节点生成哈夫曼树。这些节点
有权值,即weight,题目需要输出所有节点的值与权值的乘积之和。输出权值
5
1 2 2 5 9

37

思路:将所有节点放入集合K,若K中剩余节点大于2,则取出最小的两个节点,构造他们同时为某个节点的左右子节点,则该新节点的权值为左右儿子节点权值之和,并将该节点放入集合K。若集合K只余一个节点,则该节点为哈夫曼树的根节点。所有构造得到的中间节点的权值和即为哈夫曼树的带权路径和。在此使用小顶堆来取集合K中最小的两个值。堆结构用标准模板库中的优先队列实现。

#include<queue>
#include<stdio.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++)//输入n个叶子节点权值 
		{
			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;
}
哈夫曼树所求为最小权值路径之和:所有节点权值与节点路径长度乘积之和。即使权值最小的节点路径较长,权值大的,路径较短。所以即为所有构造节点权值之和。因为构造节点为原节点累加而来,之后树高每增加一次,构造节点累加,相当于底层节点按路径长度累加,相当于权值乘以路径长度。

猜你喜欢

转载自blog.csdn.net/joanna_or_zhouzhou/article/details/80348623