本文已参与「新人创作礼」活动,一起开启掘金创作之路。
tips:赫夫曼树or哈夫曼树,指的是同一种树,学校老师教学时称赫夫曼树,我也随之采用赫夫曼树,不用纠结名称哈
基本概念
路径:从树中一个结点到另一个结点之间的分支构成这两个结点间的路径。
结点的路径长度:两结点间路径上的分支数。
树的路径长度:从树根到每一一个结点的路径长度之和。 记作: TL
结点数目相同的二叉树中,完全二叉树是路径长度最短的二叉树。
权(weight):将树中结点赋给一个有着某种含 义的数值,则这个数值称为该结点的权。
结点的带权路径长度: 从根结点到该结点之间的路径长度与该结点的权的乘积。
树的带权路径长度:树中所有叶子结点的带权路径长度之和。
赫夫曼树:带权路径长度(WPL)最短的树。简称最优二叉树。
赫夫曼树的构造
赫夫曼树中权值越大的叶子离根越远。
贪心算法:构造赫夫曼树时首先选择权值小的叶子结点
赫夫曼算法
- 根据n个给定的权值{W1, W2, ... Wn} 构成n棵二叉树的森林 F={T1, T2.... Tn},其中Ti只有一个带权为Wi的根结点。 ==构造森林全是根==
- 在F中选取两棵根结点的权值最小的树作为左右子树,构造一棵新的二叉树,且设置新的二叉树的根结点的权值为其左右子树上根结点的权值之和。 ==选用两小造新树==
- 在F中删除这两棵树,同时将新的到的二叉树加入森林中。 ==删除两小添新人==
- 重复2和3,直到森林中只有一颗树为止,这棵树即为赫夫曼树 ==重复2、3剩单根==
举个例子
例1:有4个节点a,b,c,d,权值分别为7,5,2,4,构造赫夫曼树
例2:n=4, w={70,50,20,40} 画出HT图 要新添n-1个结点,4-1=3,4+3=7,共有七个结点 起始图
| id | weight | parent | lchild | rchild |
|---|---|---|---|---|
| 1 | 70 | |||
| 2 | 50 | |||
| 3 | 20 | |||
| 4 | 40 | |||
| 5 | ||||
| 6 | ||||
| 7 |
第一步:选用两小造新树
| id | weight | parent | lchild | rchild |
|---|---|---|---|---|
| 1 | 70 | |||
| 2 | 50 | |||
| 3 | 20 | 5 | ||
| 4 | 40 | 5 | ||
| 5 | 60 | 3 | 4 | |
| 6 | ||||
| 7 |
第二步:删除两小添新人
| id | weight | parent | lchild | rchild |
|---|---|---|---|---|
| 1 | 70 | |||
| 2 | 50 | 6 | ||
| 3 | 20 | 5 | ||
| 4 | 40 | 5 | ||
| 5 | 60 | 6 | 3 | 4 |
| 6 | 110 | 2 | 5 | |
| 7 |
重复上述两步
| id | weight | parent | lchild | rchild |
|---|---|---|---|---|
| 1 | 70 | 7 | ||
| 2 | 50 | 6 | ||
| 3 | 20 | 5 | ||
| 4 | 40 | 5 | ||
| 5 | 60 | 6 | 3 | 4 |
| 6 | 110 | 7 | 2 | 5 |
| 7 | 180 | 0 | 1 | 6 |
例3
总结
初始时有n颗树,要经过n-1次合并最终形成赫夫曼树
一颗有n个叶子结点的赫夫曼树有2n-1个结点
在赫夫曼树中,只有度为0和2的结点,没有度为1的结点