哈夫曼树(最优二叉树)
定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
路径:从树中一个结点到另一个结点之间得分支构成这两个结点间的路径。
结点的路径长度:两结点间路径上的分支数。
树的路径长度:从树根到每一个结点的路径长度之和。记作:TL
结点数目相同的二叉树中,完全二叉树是路径长度最短的二叉树
权(weight):将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。
结点的带权路径长度:从根结点到该结点之间的路径长度与该结点的权的乘积。
树的带权路径长度:树中所有叶子结点的带权路径长度之和。
因为构造这种树的算法是由哈夫曼教授于1952年提出的,所以被称为哈夫曼树,相应的算法称为哈夫曼算法。
- 1.满二叉树不一定是哈夫曼树
2.哈夫曼树中权越大的叶子离根越近
3.具有相同带权结点的哈夫曼树不唯一
哈夫曼树构造算法
哈夫曼算法:
1.根据 n 个给定的权值{W1,W2,…,Wn}构成 n 棵二叉树的森林 F={T1,T2,…,Tn},其中 Ti 只有一个带权为 Wi 的根结点
- 构造森林全是根
2.在F中选取两棵根结点的权值最小的数作为左右子树,构造一棵新的二叉树,且设置新的二叉树的根结点的权值为其左右子树上根结点的权值之和。
- 选用两小造新树
3.在 F 中删除这两棵树,同时将新得到的二叉树加入森林中
- 删除两小添新人
4.重复②和③,直到森林中只有一棵树为止,这棵树即为哈夫曼树
- 重复2、3单根
哈夫曼算法口诀:
1.构造森林全是根;
2.选用两小造新树;
3.删除两小添新人;
4.重复2、3剩单根。
下面给个例子:
特点:
1.包含n个叶子结点的哈夫曼树中共有2n-1个结点
2.哈夫曼树的结点的度数为0或2,没有度为1的结点。
3.包含n棵树的森林要经过n-1次合并才能形成哈夫曼树,共产生n-1个新结点
总结:
1、在哈夫曼算法中,初始时有 n 棵二叉树,要经过n-1次合并最终形成哈夫曼树
2、经过 n-1 次合并产生 n-1 个新结点,且这 n-1 个新结点都是具有两个孩子的分支结点
可见,哈夫曼树中共有n+n-1 = 2n - 1个结点,且其所有的分支结点的度均不为1。
哈夫曼构造算法的实现
①我们采用顺序存储结构——一维结构数组
②结点类型定义
typedef struct
{
int weight;