你比他好一点,他不会承认你,反而会嫉妒你,只有你比他好很多,他才会承认你,然后还会很崇拜你,所以要做,就一定要比别人做得好很多。
哈夫曼树相关概念及简介
在 <<大话数据结构>>之浅谈二叉树 这一篇文章我对二叉树的相关知识做了一下说明,那么这一篇文章就说一下最优二叉树,也就是哈夫曼树,在说之前,我们要先了解两个概念,那就是路径长度以及树的路径长度.
路径长度: 从树中的一个结点到另一个结点之间的分支构成两个结点之间的路径,路径上的分支数目称作路径长度.
如图 1 -1 ,比如B到D的路径长度为3,根节点到D的长度则为3,路径长度的计算还是很简单的.😌
树的路径长度 : 树的路径长度就是从树根到每一个结点的路径长度之和.
如图 1 -1,树的路径长度为 1 + 1 + 2 + 2 + 3 + 3 =12;
看完路径长度和树的路径长度,那么接下来,我们就看一下什么叫哈夫曼树.
若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。结点的带权路径WPL长度为:从根结点到该结点之间的路径长度与该结点的权的乘积。给定n个权值作为n的叶子结点,构造一棵二叉树,若带权路径WPL长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。
上面的一段话中说的是结点的带权路径已经哈夫曼树的概念,那么我们就可以计算图 1- 1中的二叉树的WPL值了, 二叉树的WPL值 = 5 x 1 + 15 x 2 + 70 x 3 + 10 x 3 = 335;
哈夫曼树的构造
上面对哈夫曼树的概念进行了阐述,那么问题来了,我们该如何把一棵二叉树构造成哈夫曼树呢?我们先看一下构造哈夫曼的的步骤,然后再结合的图 1 - 1 进行讲解.
哈夫曼树的构造总共分为四部分,
-
一、构成初始集合
对给定的n个权值{W1,W2,W3,...,Wi,...,Wn}构成n棵二叉树的初始集合F={T1,T2,T3,...,Ti,...,Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空。(为方便在计算机上实现算法,一般还要求以Ti的权值Wi的升序排列。)
-
二、选取左右子树
在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树,新二叉树的根结点的权值为其左右子树的根结点的权值之和。
-
三、删除左右子树
从F中删除这两棵树,并把这棵新的二叉树同样以升序排列加入到集合F中。
-
四、重复二和三两步,
重复二和三两步,直到集合F中只有一棵二叉树为止。 举个例子
可能上面的概念比价难以理解,那么下面我们就看一下 图 2- 1是如何改造成哈夫曼树的.
第一步,先把有权值得叶子结点按照从小到大的顺序排列成一个有序序列,即为A5,D10,B15,C70;
第二步,取头两个最小权值的结点作为一个新结点N1的两个子结点,注意相对较小的的孩子是左孩子,这里A就是N1的左孩子,D为N1的右孩子,如图2 -2 所示.新结点的权值为两个叶子结点的权值之和 5 + 10 = 15;
第三步,将N1替换A与E,插入有序序列中,保持从小到大的排序,即 N1 15,B15,C70;
第四步,重复步骤2,将N1与B作为一个新结点N2的两个子结点,如图 2 - 3 所示, N2的权值 = 15 + 15 = 30;
第五步,将N2替换N1与B,插入有序序列中,保持从小到大的排序,即 N2 30,C70;
第六步,重复步骤2,将N2和C作为一个新结点T的两个子结点,如图2 -4 所示.由于T就是根结点,所以完成哈夫曼树的构造.
那么我们就可以计算构造完成的哈夫曼树的路径长度WPL = 1 x 70 + 2 x 15 + 3 x 10 +3 x 5 = 145;那么2 - 2中二叉树的WPL值 = 5 x 1 + 15 x 2 + 70 x 3 + 10 x 3 = 335;WPL值差不多差了两倍...
总结:哈夫曼树又称为最优二叉树,因为他的效率是同等权值二叉树中最高的,做一程序猿简单,做一个有高效率的程序员难.与君共勉.希望这篇文章能对您有所帮助.谢谢.