最近写了一个哈夫曼编码小程序。对于数据结构书上介绍的算法硬是没看懂,而只是看懂了图示,所以就用了自己的方式来做。
程序运行如下图:
写了一个哈夫曼树类。可以对任何数据进行编码。测试的话,只需要输入要进行编码的字符串就行了,会输出编码方案(就是编码后对应的01序列),对应的哈夫曼树形态,和编码结果。
我的哈夫曼树类,在内部维护了一个链式二叉树。当输入一个字符串作为要编码的对象时,做如下几步:
1.先统计各个字符出现的次数。比如:“Steven Kyle Lee”中的e出现了5次。
2.用字符和它的出现次数(作为权值),new出对应的树节点。这些节点纳入一个线性表(list容器),这一步相当于是创建森林了,只是每个树都只有一个根节点。
3.构建哈夫曼树。做一个循环,找出森林中权值最小的2棵树,new出一个树节点,其左右子树分别接上权值最小的2棵子树,其自身的权值是找出的权值最小2棵子树的和。删除找出的权值最小的2棵子树。new出来的这个结点纳入list容器.(实际中,这一步,是在其中一个权值最小的节点上操作的,只删除另一个权值最小的节点)。循环退出条件是list容器只剩下一颗树。
4.经过步骤3后,list容器剩下的那棵树即是一棵哈夫曼树了。其实以上3步,就是模拟了书上图示的过程。
5.创建哈夫曼树完成后,就要知道某个字符对应的哈夫曼编码了(01序列)。这个比较简单,递归遍历树,进入左子树编码序列加0,进入右子树编码序列加1。达到叶子节点后,就用map容器创建映射关系(key是要编码的字符,Value是这个字符对应的01序列)
OK,我的算法大概就如上所述。附上源代码(VS2008),高手多多指教!