`
什么世道
  • 浏览: 219367 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

哈夫曼编码

阅读更多

 哈弗曼编码几乎是所有压缩算法的基础,其实这个算法并不复杂,简单的理解就是,如何用更短的bit来编码数据

    我们知道普通的编码都是定长的,比如常用的ASCII编码,每个字符都是8个bit:

字符编码

A 00101001
B 00101010
C 00101011

   这样,计算机就能很方便的把由0和1组成的数据流解析成原始信息,但我们知道,在很多情况下,数据文件中的字符出现的概率是不均匀的,比如在一篇英语文章中,字母“E”出现的频率最高,“Z”最低,如果我们使用不定长的bit编码,频率高的字母用比较短的编码表示,频率低的字母用长的编码表示,岂不是可以大大缩小文件的空间吗?
    但这就要求编码要符合“前缀编码”的要求,即较短的编码不能是任何较长的编码的前缀,这样解析的时候才不会混淆,比如下面的编码方法就符合前缀原则:

字符编码

A 101
B 0
C 1000
D 11
E 1001

    根据这个码表,下面一段数据就可以唯一解析成原始信息了:
    11101001110001011010 – DABBDCEAAB

    要生成这种编码,最方便的就是用二叉树,考察一下下面这个树

 

    现在我们可以开始考虑压缩的问题,如果有一篇只包含这五个字符的文章,而这几个字符的出现的次数如下:
    A: 6次
    B : 15次
    C: 2次
    D : 9次
    E: 1次
    用过用定长的编码,每个字符3bit,这篇文章总长度为:
    3*6 + 3*15 + 3*2 + 3*9 + 3*1 = 99

    而用上面用二叉树生成的编码,总长度为:

 

    3*6 + 1*15 + 4*2 + 2*9 + 4*1 = 63

 

可以看出,构造更优的二叉树,原则就是权重越大的叶子,距离根应该越近,而我们的终级目标是生成“最优”的二叉树,最优二叉树必须符合下面两个条件:

  1. 所有上层节点都大于等于下层节点。
  2. 某节点,设其较大的子节点为m,较小的子节点为n,m下的任一层的所有节点都应大于等于n下的该层的所有节点。

    上面这个例子是比较简单的,实际的文件中,一个字节有256种可能的取值,所以二叉树的叶子节点多达256个,最终的树形可能非常复杂,但有一种非常精巧的算法可以快速地建起一棵最优二叉树,这种算法由D.Huffman(戴~哈夫曼)提出,下面我们先来介绍哈弗曼算法的步骤,然后再来证明通过这么简单的步骤得出的树形确实是一棵最优二叉树。
    哈夫曼算法的步骤是这样的:

  • 从各个节点中找出最小的两个节点,给它们建一个父节点,值为这两个节点之和。
  • 然后从节点序列中去除这两个节点,加入它们的父节点到序列中。
  • 重复上面两个步骤,直到节点序列中只剩下唯一一个节点。这时一棵最优二叉树就已经建成了,它的根就是剩下的这个节点。

        比如上面的例子,哈弗曼树建立的过程如下:

        1) 列出原始的节点数据:

        2) 将最小的两个节点C和E结合起来:

        3) 再将新的节点和A组合起来

        4) 再将D节点加入

        5) 如此循环,最终得到一个最优二叉树

        生成的数据文件长度为:
        3*6 + 1*15 + 4*2 + 2*9 + 4*1 = 63

        下面我们用逆推法来证明对于各种不同的节点序列,用哈弗曼算法建立起来的树总是一棵最优二叉树:

    • 当这个过程中的节点序列只有两个节点时(比如前例中的15和18),肯定是一棵最优二叉树,一个编码为0,另一个编码为1,无法再进一步优化。
    • 然后往前步进,节点序列中不断地减少一个节点,增加两个节点,在步进过程中将始终保持是一棵最优二叉树,这是因为:
      1. 按照哈弗曼树的建立过程,新增的两个节点是当前节点序列中最小的两个,其他的任何两个节点的父节点都大于(或等于)这两个节点的父节点,只要前一步是最优二叉树,其他的任何两个节点的父节点就一定都处在它们的父节点的上层或同层,所以这两个节点一定处在当前二叉树的最低一层。
      2. 这两个新增的节点是最小的,所以无法和其他上层节点对换。符合我们前面说的最优二叉树的第一个条件。
      3. 只要前一步是最优二叉树,由于这两个新增的节点是最小的,即使同层有其他节点,也无法和同层其他节点重新结合,产生比它们的父节点更小的上层节点来和同层的其他节点对换。它们的父节点小于其他节点的父节点,它们又小于其他所有节点,只要前一步符合最优二叉树的第二个条件,到这一步仍将符合。

        这样一步步逆推下去,在这个过程中哈弗曼树每一步都始终保持着是一棵最优二叉树。从而实现哈夫曼压缩——最优的无损压缩、

 

下一篇博文将主要用代码实现哈夫曼压缩和解压缩:

http://yacare.iteye.com/blog/1955831

 

分享到:
评论

相关推荐

    哈夫曼编码系统(C语言实现)

    利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传输数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向...

    三元哈夫曼编码 哈夫曼树

    详细描述了哈夫曼树的构造方法,同时推广到三元哈夫曼编码,并用C语言于VC++上实现

    哈夫曼编码 将文本哈夫曼编码并求平均码长

    这个代码是用C/C++实现哈夫曼编码并将编码输出。 文本为操作者输入,,对各字符进行频率统计,然后进行哈夫曼编码,并将编码结果输出,同时可求得平均码长。

    哈夫曼树与哈夫曼编码

    哈夫曼树与哈夫曼编码 建立哈夫曼树并计算哈夫曼编码

    哈夫曼编码数据压缩_哈夫曼编码_哈夫曼编码实现数据压缩_

    哈夫曼编码实现文本文件的压缩,可作为数据压缩作业的参考

    哈夫曼编码/译码实现

    压缩文件即读文件,统计文件中的字符个数,对文件进行哈夫曼编码和译码,并将编码译码后的字符存储在文件中。 完成功能的详细说明: 1.统计文本文件中各字符的频率(涉及读文件,统计字符个数); 2.对文件中的...

    数字彩色图像的哈夫曼编码与解码的matlab实现

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

    基于哈夫曼编码的图像压缩技术研究

    摘 要:哈夫曼编码是一种数据编码方式,以哈夫曼树——即最优二叉树,用带权路径长度最小的二叉树,对数据进行重编码,经常应 用于数据压缩。在计算机信息处理中,“哈夫曼编码”是一种一致性编码法(又称“熵编码法...

    用哈夫曼编码实现文件压缩

    利用哈夫曼编码思想,设计对一个文本文件(.txt)中的字符进行哈夫曼编码,生成编码压缩文件(.txt),并且还可将压缩后的文件进行解码还原为原始文本文件(.txt)。 实现的功能: (1)压缩:实现对文件的压缩,生成...

    哈夫曼编码课程设计

    哈夫曼编码课程设计,我要让所以人都知道写一个哈夫曼编码树便不是难事。

    哈夫曼编码C++实现

    哈夫曼编码是广泛用于数据文件压缩的十分有效的编码方式,其压缩率通常在20%—90%之间。哈夫曼编码算法是通过使用字符在文件中出现的频率表来构造最优前缀码的贪心算法。所谓前缀码,即是任一字符的编码都不是其他...

    用c语言实现哈夫曼编码

    这是那个用c语言来实现的哈夫曼编码程序,可以对输入的数据进行相应的编码……

    c语言实现哈夫曼编码

    c语言实现哈夫曼编码,并求平均码长 c语言实现哈夫曼编码,并求平均码长

    基于C++文件的哈夫曼编码与解码.zip

    本人的小工具仅针对英文大小字母及 ' '\n' ' ' 字符针对性的进行了哈夫曼编码,若想实现中文及各种支持语言的编码,可在此代码基础上,进行优化。 详细介绍参考:...

    数据结构哈夫曼编码实验报告.doc

    一、【问题描述】 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本 。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数 据进行译码,此实验即设计这样...

    c++ 源代码 哈夫曼树 哈夫曼编码

    c++ 源代码 哈夫曼树 哈夫曼编码 部分代码如下: #include"Huffman.h" #include"hfmTree.h" #include using namespace std; int main() { cout~~~~~~~~~~~~~welcome to Huffman encodrding&decoding system ~~~~~~...

    哈夫曼编码器设计实验报告.zip_slidefi3_哈夫曼编码_哈夫曼编码器_对一段数据序列进行哈夫曼编码

    要求对一段数据序列进行哈夫曼编码,使得平均码长最短,输出各元素编码和编码后的数据序列。 ①组成序列的元素是[0-9]这10个数字,每个数字其对应的4位二进制数表示。比如5对应0101,9对应1001。 ②输入数据序列的...

    哈夫曼编码译码器

    数据结构课程设计,实现哈夫曼编码,译码,打印哈夫曼树

Global site tag (gtag.js) - Google Analytics