哈夫曼树,又称最优二叉树,是一种带权路径长度最短的二叉树。带权路径长度就是指树中所有的叶结点的权值乘上其到根结点的路径长度。
哈夫曼树是如何构造的呢,就是在一个你需要加入树的节点的集合中,选取两个最小的元素组成一个树,此时,并将这个树加入到这个集合中,再从这个集合选出最小的两个节点组成一个树,并将这个树加入到集合中,循环往复,知道这个集合里只剩下一棵树为止。如图:
这里首先先选取了最小的两个元素1,2,合并为了一个树,之后将合并后生成的新的树根加入到了这个集合中,接下来就有两个选择了,可以选择2和本来就有的3或者选择2和新填入的三,然后像第一步那样继续操作,两种方法得到的结果都是一样的
那么如何实现哈夫曼树呢,这里就要用到队列了
⒈把n个终端节点加入优先队列,则n个节点都有一个优先权Pi,1 ≤ i ≤ n
⒉如果队列内的节点数>1,则:
⑴从队列中移除两个最小的Pi节点,即连续做两次remove(min(Pi), Priority_Queue)
⑵产生一个新节点,此节点为(1)之移除节点之父节点,而此节点的权重值为(1)两节点之权重和
⑶把(2)产生之节点加入优先队列中
⒊最后在优先队列里的点为树的根节点
哈夫曼树的应用——哈夫曼编码
说起哈夫曼树的由来,有个很有意思的故事,当年哈夫曼在MIT攻读博士学位,他和修读信息论课程的同学得选择是完成学期报告还是期末考试,于是哈夫曼毫不犹豫的选择了学期报告题目:查找最有效的二进制编码。哈夫曼进行了新的探索,最终发明了哈夫曼树。这要就不得不提到他的应用了--哈夫曼编码。简单来说,就是左子树代表0,右子树代表1,而字符又是可以用0和1来表示的,再根据字符出现的频数,使用频率高的用短码,使用频率低的用长码,就可以设计最优的编码方案了。