建立哈夫曼树并计算带权路径C++实现

  • 建立一个哈夫曼树的过程,核心思想在于找出集合中最小和次小的两个元素从集合中删除并将其构建为二叉树的左右孩子,然后将其data域值相加得到一个新的元素插入原来的集合中继续找最小和次小元素重复操作,但是如果上一次插入的元素并不是新找到的最小元素和次小元素之一,我们就得新建立一个子树。
    而计算WPL也是相对简单的,核心代码必须要求得每个节点在哈夫曼树中的深度,只需要从节点开始,依次访问双亲节点,直到双亲节点为空或者0,再依次相乘相加即可。
#include<iostream>
#include<stack>
#include<queue>
using namespace std;
#define MAX 100
int arr[MAX][MAX];
int flag[MAX];//标识是否访问过某一元素
struct HT//哈夫曼树节点
{
	int data;
	int parent,lchild,rchild;
};
void selectmin(HT arr[], int& s1, int& s2,int n)//找到不相同的最小两个元素
{
	int min=-1000;
	for (int i = 1; i <= n; i++)
	{
		if (arr[i].parent == 0)
		{
			min = i;
			break;
		}
	}
	for (int j = 1; j <= n; j++)
	{
		if(arr[j].parent==0)
			if (arr[j].data < arr[min].data)
				min = j;
	}
	s1 = min;
	for (int i = 1; i <= n; i++)
	{
		if (arr[i].parent == 0 && i!=s1)
		{
			min = i;
			break;
		}
	}
	for (int j = 1; j <= n; j++)
	{
		if(arr[j].parent==0 && j!=s1)
			if (arr[j].data < arr[min].data)
				min = j;
	}
	s2 = min;
}
int finddeep(HT t[],HT a)//计算节点位于第几层
{
	int cnt = 0,flag=1;
	HT b = a;
	while (b.parent)
	{
		cnt++;
		b = t[b.parent];
	}
	return cnt;
}
int findWPL(HT t[],int n)//计算哈夫曼树的带权路长
{
	int cnt = 0;
	for (int i = 1; i <= n; i++)
	{
		cnt += finddeep(t, t[i]) * t[i].data;
		cout << t[i].data << "的带权路径值:" << finddeep(t, t[i]) * t[i].data << endl;
	}
	return cnt;
}
void createHT(int n)//创建一个哈夫曼树
{
	int m = 2 * n - 1,s1,s2;
	HT *p = new HT[m+1];
	for (int i = 1; i <= m; i++)
	{
		p[i].lchild = 0;
		p[i].rchild = 0;
		p[i].parent = 0;
	}
	cout << "输入各个节点的权值:";
	for (int i = 1; i <= n; i++)
	{
		cin>>p[i].data;
	}
	for (int i = n + 1; i <= m; i++)
	{
		selectmin(p, s1, s2, i-1);
		p[s1].parent = i;
		p[s2].parent = i;
		p[i].lchild = s1;
		p[i].rchild = s2;
		p[i].data = p[s1].data + p[s2].data;
	}
	cout << "WPL值为:" << findWPL(p, n)<<endl;
}
int main()//哈夫曼树题目
{
	int n;
	cout << "请输入哈夫曼树的节点数:";
	cin >> n;
	createHT(n);
	return 0;
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值