简介:
又称最优二叉树
给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,成这样的树为最优二叉树,权值较大的结点离根较近
名词:
路径长度:在一条路径中,没经过一个节点读经的长度都加一
结点的权:给每个结点赋予一个新的数值,被称为结点的权
结点的带权路径长度:从根节点到该节点的路径长度与该节点的权的乘积
树的带权路径长度为树中所有的叶子结点的带权路径长度之和。
构建哈夫曼树:
遵循原则:
权重越大的结点离树根越近
- 选出数据中最小的两个数据,构建成二叉树的左儿子和右儿子,而跟的数据为两者之和
2.将刚才合成的数据作为右孩子,左孩子从未处理的数据中选出一个最小的作为左孩子,他们的根同样为左孩子的权值和
3.重复上述步骤 即可构造处哈夫曼树
代码:
```cpp
/*哈夫曼树*/
#include<stdio.h>
#include <malloc.h>
/*哈夫曼树结构特点*/
typedef struct {
/*结点权重*/
int weight;
/*定义左孩子 右孩子 父节点在数组中的位置下标*/
int parent, left, right;
}HTNode, *HuffmanTree;
/*构建哈夫曼树*/
/*HT-存储哈夫曼树的数组 w-存储结点权重的数组 n-节点个数*/
void CreatHuffManTree(HuffmanTree *HT, int *w, int n)
{
if (n <= 1)
return;
/*树的总结点个数, n是叶子节点数*/
int m = 2 * n - 1;
/*0号位置不用*/
*HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode));
HuffmanTree p = *HT;
/*初始化哈夫曼树中所有的结点*/
for (int i = 0; i <= n; i++)
{
(p + i)->weight = *(w + i - 1);
(p + i)->parent = 0;
(p + i)->left = 0;
(p + i)->right = 0;
}
/*从数组的下表为n+1开始初始化树中除了叶子节点外的结点*/
for (int i = n + 1; i <= m; i++)
{
(p + i)->weight = 0;
(p + i)->left = 0;
(p + i)->right = 0;
(p + i)->parent = 0;
}
/*构建哈夫曼树*/
for (int i = n + 1; i <= m; i++)
{
int s1, s2;
//Select()
(*HT)[s1].parent = (*HT)[s2].parent = i;
(*HT)[i].left = s1;
(*HT)[i].right = s2;
(*HT)[i].weight = (*HT)[s1].weight + (*HT)[s2].weight;
}
}