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;
}
}
如有错误,敬请指正。
您的收藏与点赞都是对我最大的鼓励和支持!