哈夫曼树,又称最优树,是一类带权路径长度最短的树。
路径长度:从树中一个结点到另一个结点之间的分支构成这两个结点之间的路径,而路径长度,则是路径上的分支数目。
树的路径长度:从树根到每一结点的路径长度之和。
树的带权路径长度:树中所有带权结点的路径长度之和。
如图,分别有以下三棵二叉树,都有4个子节点a、b、c、d,分别带权7、5、2、4,那么它们的带权路径长度分别为:
(a)72 + 52 + 22 + 42 = 36
(b)73 + 53 + 21 + 42 = 46
(c)71 + 52 + 23 + 43 = 35
可以看到:权值越大的叶子结点越靠近根结点,而权值越小的叶子结点越远离根结点。
值越大权越小。
哈夫曼树的构造:每次取两个最小的树组成的二叉树
比如:我们要设置一个程序,将学生们的成绩(a)分成5个等级。
bad(a<60)、pass(60<a<69)、general(70<a<79)、good(80<a<89)、excellent(90<a<100);
if ( a < 60 ) { bad }
else if ( a<70){ pass }
else if ( a<80){ general }
else if ( a<90){ good }
else { excellent }
这样计算虽然可以,但是会有重复操作,而且成绩a是不均匀分布的,大多数数据会经历好几次的判断,才得出结果,用树表示,如图a。
假设成绩a的分布规律如下:
假设以5、15、40、30和10为权构造一颗五个叶子结点的哈夫曼树,则大部分数据可以经过较少的比较次数得出结果。如图b。
又因为每个判定框高中都有两次比较,那么将两次比较分开,则得到图c的树。
以上就是哈夫曼树的一个构造过程。
哈夫曼树的应用:哈夫曼编码
我们知道以前进行远距离的通信方式是采用电报的心思,将文字转成二进制字符进行传输。
比如:ABACCDA,那么可以将ABCD编码为:00、01、10、11四种字符,表示为:00010010101100 一共14位,对方接收到后,按二位一分译码。
但是!
如果这是一段很长的机密的话,怎么才能用最短的编码表示出来呢?
那最好是长短不一的,省空间嘛。
所以,我们假设ABCD编码分别为0、00、1和01,则上述的电文可转换为总长为9的字符:000011010. 但是对方接收到后,可能就看不懂了,因为前面4个0,不知道你表示的是A还是B。
那么得出结论,
前缀编码:如果要设计长短不一的编码,则任一个字符的编码都不是另一个字符的编码的前缀。
那么用二叉树来设计二进制的前缀编码最优的编码就叫做哈夫曼编码。
ABACCDA(01001101101110)总长14?
那么最优的呢? 如图: