创建哈夫曼树并求带权路径长度

创建哈夫曼树并求带权路径长度

【问题描述】根据给定的权重,构造哈夫曼树,输出其带权路径长度。
【输入形式】输入权重,空格作为分隔,回车结束,权重个数小于10。
【输出形式】哈夫曼树的带权路径长度。
【样例输入】5 6 2 9 7
【样例输出】65
【样例说明】
【评分标准】

#include<iostream>
#include<cstdlib>
#include<cstdio>
#define MAX_SIZE 10
#define MAX 100
using namespace std;
typedef struct
{
	int weight;
	int parent, lchild, rchild;
}HTNode, *HuffmanTree;
void Select(HuffmanTree HT, int k, int &s1, int &s2)       //在HT[1...i-1]中选择parent为0,且weight最小的两个结点,分别赋给s1,s2
{
	int i, min;
	min = MAX;
	for (i = 1; i <= k; i++)
	{
		if (HT[i].parent == 0 && min > HT[i].weight)
		{
			s1 = i;
			min = HT[i].weight;
		}
	}
	min = MAX;
	for (i = 1; i <= k; i++)
	{
		if (i != s1 && HT[i].parent == 0 && HT[i].weight < min)
		{
			s2 = i;
			min = HT[i].weight;
		}
	}
}
void CreateHuffmanTree(HuffmanTree &HT, int *w, int n)     //创建哈夫曼树,不求哈夫曼编码HC
{
	int m, i, s1, s2;
	if (n <= 1)
		return;
	m = 2 * n - 1;
	HT = new HTNode[m + 1];
	for (i = 1; i <= m; i++)
	{
		HT[i].weight = i <= n ? w[i - 1] : 0;
		HT[i].parent = HT[i].lchild = HT[i].rchild = 0;
	}
	s1 = s2 = 0;
	for (i = n + 1; i <= m; i++)                           //建哈夫曼树
	{
		Select(HT, i - 1, s1, s2);
		HT[i].lchild = s1;
		HT[i].rchild = s2;
		HT[s1].parent = HT[s2].parent = i;
		HT[i].weight = HT[s1].weight + HT[s2].weight;
	}
}
void PrintHuffmanTree(HuffmanTree HT, int n)
{
	int m, i;
	m = 2 * n - 1;
	for (i = 1; i <= m; i++)
	{
		cout << i << "   " << HT[i].weight << "   " << HT[i].parent << "   " << HT[i].lchild << "   " << HT[i].rchild << endl;
	}
}
int WeightedPathLength(HuffmanTree HT, int n)              //求带权路径的长度
{
	int len, i, k, t;
	len = t = 0;
	for (i = 1; i <= n; i++)
	{                                                      //哈夫曼树的特性决定:每一个双亲必有左右孩子,根节点除外
		for (k = HT[i].parent, t = 0; k != 0; k = HT[k].parent)                          //到根节点结束,即求出了路径长度
			t++;
		len += HT[i].weight*t;
	}
	return len;
}
int main(void)
{
	int n, len, w[MAX_SIZE];
	HuffmanTree HT;
	n = 0;
	do                                                     //输入权重,按回车结束
	{
		cin >> w[n];
		n++;
	} while (getchar() != '\n');
	CreateHuffmanTree(HT, w, n);
	len = WeightedPathLength(HT, n);
	cout << len << endl;
	system("pause");
	return 0;
}

用例二叉树:
该例二叉树
存储结构:
存储结构
运行案例:
运行案例
说明:
1.在哈夫曼树的构造过程中,需要频繁地访问结点的双亲,故采用静态三叉链表。
2.n个叶子结点的哈夫曼树,结点总数是确定的,共有2n-1个结点。
3.哈夫曼树上只含有度为0和度为2的结点,不存在度为1的结点。
4.构造n个权值的哈夫曼树,共需进新n-1次合并。

  • 4
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值