一次一小步之用C++实现Huffman文件压缩

首先介绍下Huffman算法:


哈夫曼编码(Huffman Coding)是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长 度最短的码字,有时称之为最佳编码,一般就叫作Huffman编码。


明确几个概念:(主要来自高教出版的数据结构与算法,不想看的这里可以直接跳过,点这里

 

结点路径长:如果n1,n2,n3,...,nk是树中的节点序列,并且ni是ni+1(1=<i<=k-1)的父结点,这节点序列n1,n2,n3,...,nk称为n1~nk的一天路径,路径长度就是k-1个长度之和。

树的路径长度:从树的根到树中每一个结点的路径长度之和。

 

二叉树

如上图所示,假如每个相邻结点之间长度为1,从A到C之间的路径长度即为2

 

 

扩充二叉树:每当在原来的二叉树出现空子树时,就加上一个特殊的结点,如下图

 

外结点:上图方形的结点;

内结点:圆形的结点;

外路长:根结点到每个外节点的路长之和;

内路长:根结点到每个内结点的路长之和;

加权路长:设有m个实数w1,w2,w3,...,wm,构造一棵有m个外结点的扩充二叉树,并按一定的方法将数w1,w2,w3,...,wm与这m个外结点联系起来,称SUM(wjlj)为二叉树额加权路长,其中lj为某个外结点外路长,wj是与此结点相对应的实数,如上图的实数;

 

 

显然,上图的加权路长为2 * 3 + 1 * 3 + 3 * 2 + 6 * 3 + 7 * 4 + 4 * 4 + 5 * 3 + 8 * 3,但是,你发现了吗?将1、2和7、4的未知替换之后,加权路长会减少,对,我么离Huffman不远了。

 

现在,我们需要构造这样一棵二叉树,它的出现使我们有最小的加权路长,因而我们能用这个原理来压缩信息。

至于怎么用,且听我慢慢说来:

 

计算机里文件的最小单位是字节Byte,8位,采用等长编码,共256个码,于是我们将他们构成一颗二叉树,每个码都对应一个二叉树的叶结点,这棵树有511个结点,共9层。由于是等长编码,这棵二叉树的扩充二叉树的每个权值的大小相同,不妨定为1/256,于是,这颗扩充二叉树的加权路长为1/256*8*256=8,刚好是每个字节有的位数。但是,大家知道,文件中每个字符出现的频率是不一样的,比如26个字母的出现的频率不一致造成了你现在的键盘布局。

 

于是,我们不妨统计一下每个字符的频率,将频率作为上面提到的256个码扩充二叉树的权值,这样,只要通过一定的算法构造一课最优的扩充二叉树,我们就可以达到信息压缩的目的。

 

可能看得有点迷糊,不要紧,看下面的例子,顺便提下前缀性编码

 

假如一种信息由a,b,c,d组成,各字符出现的频率是0.12、0.4、0.15、0.33,用一个二进制数字串,对每个字符进行编码,使任意一个字符的编码不会是任何其他字符编码的前缀。通常把编码的这种特性佳作“前缀性”,“前缀性”使任意两个字符之间不需要加分隔符。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值