数据结构——哈夫曼树的创建过程

1.基本概念

(1)结点路径长度:从树根到结点的分支树;

(2)树的路径长度:从树根到每一个结点的路径长度的总和;

(3)树的带权路径长度(WPL):树中所有叶子结点的带权路径之和。

2.哈夫曼树(Huffman)

(1)哈夫曼树是带权路径长度WPL最小的二叉树(也称为最优二叉树);

(2)创建哈夫曼树的过程:找出权值较小的两个,创建一棵树,然后将它加入集合,继续循环找,直到集合中剩余一个为止。

(3)为什么同一段权值有可能创建出来的哈夫曼树不同?

因为会出现相同的权值左右子树的放置每个人放的位置不同。

3.创建Huffman树的代码: 

#include<stdio.h>
#include<iostream>
using namespace std;

typedef struct node
{
	int weight;//权值
	int parent;//父节点下标
	int left;//左孩子的下标
	int right;//右孩子的下标
	int flag;//标记当前的元素是否被选择过

}HaffNode;

void CreateHaff(int* weight, int n, HaffNode* haff);

int main()
{
	int weight[] = { 5,15,40,30,10 };
	int n = sizeof(weight) / sizeof(weight[0]);
	HaffNode* phaff = (HaffNode*)malloc(sizeof(HaffNode) * (2 * n - 1));
	CreateHaff(weight, n, phaff);
}

void CreateHaff(int* weight, int n, HaffNode* haff)
{
	int i, j;
	int min1, min2;
	int min1x, min2x;//最小的和次小的下标
	//初始化haff数组
	for (i = 0;i < 2 *( n - 1);i++)
	{
		if (i < n)
		{
			haff[i].weight = weight[i];
		}
		else
			haff[i].weight = 0;
		haff[i].parent = 0;
		haff[i].left = 0;
		haff[i].right = 0;
		haff[i].flag = 0;
	}
	//构造haff,其实就是构建数组元素
	for (i = 0;i < n - 1;i++)
	{
		min1 = min2 = 65535;
		min1x = min2x = 0;

		//查找两个最小的
		for (j = 0;j < n + i;j++)//每次创建一颗新的则放到数组中,所以每次查找最小的时候多一个
		{
			if (haff[j].weight < min1 && haff[j].flag == 0)
			{
				min2 = min1;//将现有的最小值给了min2
				min2x = min1x;
				min1 = haff[j].weight;
				min1x = j;
			}
			else if (haff[j].weight < min2 && haff[j].flag == 0)
			{
				min2 = haff[j].weight;
				min2x = j;
			}
		}
		//用最小的和次小的创建一棵树
		haff[n + i].weight = min1 + min2;
		haff[n + i].left = min1x;
		haff[n + i].right = min2x;

		//将最小的和次小的父节点下标修改
		haff[min1x].parent = n+i;
		haff[min2x].parent = n + i;

		//最小的和次小的flag重置
		haff[min1x].flag = 1;
		haff[min2x].flag = 1;
	}
}


		

如有错误,敬请指正。

您的收藏与点赞都是对我最大的鼓励和支持!

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Sweep-

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

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

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

打赏作者

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

抵扣说明:

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

余额充值