数据结构:赫夫曼树

路径:从树中一个结点到另一个结点之间的分支构成两个结点之间的路径

路径长度:路径上的分支数目称作路径长度。

树的路径长度:从树根到每一结点的路径长度之和。

带权路径长度为从该结点到树根之间的路径长度与结点上权的乘积。树的带权路径长度为树中所有叶子节点的带权路径长度之和。

带权路径长度最小的二叉数被称为赫夫曼树

struct HaffMan
{
	int weight;//权值
	int leftindex;//左孩子的位置
	int rightindex;//右孩子的位置
	int parentindex;//父节点的位置
	int flg;//标记
};
void Create(HaffMan* haff, int* num, int n)//创建赫夫曼树
{
	int min1, min2, min1index, min2index;//min1最小值,min2次小值,min1index最小值位置,min2index次小值位置
	for (int i = 0; i < 2 * n - 1; i++)//n个结点创建赫夫曼树,常见出的赫夫曼树结点为2*n-1
	{
		if (i < n)
		{
			haff[i].weight = num[i];
		}
		else
			haff[i].weight = 0;
		haff[i].leftindex = -1;
		haff[i].rightindex = -1;
		haff[i].parentindex = -1;
		haff[i].flg = 0;//初始化
	}
	for (int i = 0; i < n-1; i++)//n个节点需要n-1次比较可以找到最小值与次小值
	{
		min1 = min2 = 65535;
		min1index = min2index = -1;
		for (int j = 0; j < n + i; j++)
		{
			if (haff[j].weight < min1 && haff[j].flg == 0)
			{
				min2 = min1;
				min2index = min1index;
				min1 = haff[j].weight;
				min1index = j;
			}
			else if (haff[j].weight < min2 && haff[j].flg == 0)
			{
				min2 = haff[j].weight;
				min2index = j;
			}
		}
		//用两个最小的构建新的结点
		haff[n + i].weight = min1 + min2;
		haff[n + i].leftindex = min1index;
		haff[n + i].rightindex = min2index;
		haff[min1index].parentindex = n + i;
		haff[min2index].parentindex = n + i;
		haff[min1index].flg = haff[min2index].flg = 1;
	}
}
void HaffCode(HaffMan*haff,vector<vector<int>>&vv,int n)//构建赫夫曼树编码,左子树为0,右子树为1
{
	int child, parent;
	vector<int>s;
	for (int i = 0; i < n; i++)
	{
		child = i;
		parent = haff[child].parentindex;
		s.clear();//每次都要清空vector里面的数
		while (parent != -1)
		{
			if (haff[parent].leftindex==child)
				s.push_back(0);
			else
				s.push_back(1);
			child = parent;
			parent = haff[child].parentindex;
		}
		vv.push_back(s);
	}
}
void main()
{
	vector<vector<int>>vv;
	int num[] = { 10,30,40,15,5 };
	int n = sizeof(num) / sizeof(num[0]);
	HaffMan haffp[9];
	Create(haffp, num, n);
	HaffCode(haffp, vv, n);
	for (int i = 0; i < vv.size(); i++)
	{
		for (int j = vv[i].size() - 1; j >= 0; j--)
		{
			cout << vv[i][j];
		}
		cout << endl;
	}
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秉麟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值