代码改变世界

(堆的应用)Huffman赫夫曼树的建立

  捣乱小子  阅读(5329)  评论(1编辑  收藏  举报

日后的纠正

最近才发现自己的代码有问题,也是在后来做另一个有关哈夫曼实验的时候才发现,在代码当中有很多时候是用new来建立一个新的节点,就包括从最小堆中取出权重最小的节点(这个没有错误),根据两个权重最小节点得出新的节点和往最小堆中插入这个新的节点。问题出在后两个,因为在中间那一步就对left和right设置了parent(看了我的代码的就该很清楚了),其实如果这样下去是很繁琐的,因为new来new去,赋值来赋值去,非常容易搞混。

我测试了一下,会把一部分孩子(left或者right)的parent指针搞错,所以今天2011-12-17我更新了Huffman哈夫曼代码。另外值得一提的是,网络上我看了很多类似的代码,发现有很多是错误的,而最重要的错误就在这里。


建立Huffman树的基本思路:给定有权重的一系列数据(带权重),从中挑选最小权重的两个数据,组成一棵树,得到的父节点再插入到数据系列当中。

开始的时候按着严老师的办法,是借助顺序表来完成Huffman树的建立;同样,在建树过程中要从顺序表中选择比较小的两个数,相加后再插入到表尾,如此往复,直到所有给出的点都插入为止。通过最小堆来建树也很灵活便捷。堆的性能高,排序时间复杂度为nlog(2)n,利用最小堆,就可以将很快找出最小的元素(总是在顶部)。

 

下面8步立刻掌握利用最小堆来建立Huffman树。

看图解说

①原图(已经是最小堆);

②交换堆的首元素(权重肯定是最小的)和最后一个元素对换;

③交换后删除最后一个元素(复制出来),其实也不是真正的删除,只是size-1这个操作而已;调换后就不是堆了,重新调整heap为最小堆,调整可以用递归调用,也可以用下标作为判断条件,我的代码用的是下标判断条件;

④继续②;

⑤弹出权重最小的,调整;将权重两个最小点复制出来后,组成新的父节点,调整他们之间的内部指针关系;

⑥调整后;

⑦插入新节点,调整;

⑧调整后。

 

image

 

以上做了第一遍的操作,继续做下去知道堆中只剩下最后一个元素为止,再将root指向其就可以了,下面是代码。如此下来,Huffman树就建好了。

ps:下面的代码在建立最小堆和在堆中取出权重最小Huffman节点的时候,因为在HuffmanNode设计过程当中没有加入weight(权重),因此就姑且用了data(int型)的值作为权重


Huffman节点数据结构设计:

最小堆类:

Huffman类:

 

Huffman(哈弗曼,赫夫曼)在通信领域用途很大,在文件压缩技术也有所运用,做些笔记,以后有用,与大家共享,欢迎讨论:)。

捣乱小子 2011-12-15

点击右上角即可分享
微信分享提示