数据结构——哈夫曼树与哈夫曼编码

本文介绍了哈夫曼编码,一种基于字符频率的文本压缩算法。通过建立哈夫曼树,实现可变长度编码,确保编码无前缀冲突。讨论了如何构建最小加权外部路径长度的霍夫曼树,以及压缩过程包括确定频率、建立霍夫曼树和生成编码。

1.哈夫曼编码 Huffman code:

  是一种文本压缩算法,这种算法依据的是不同符号在一段文本中相对出现的频率。假设一个文本是由a,u,x,z组成的字符串,其长度为1000,每个字符用1字节来存储,共需要1000字节,即8000位。如果每个字符用2位二进制来编码:00=a, 01=x, 10=u, 11=z.那么,用2000位空间即课表示1000个字符。此外,我们还需要一定的空间来存放编码表,它可以采用如下的存储格式:

    符号个数,代码1,符号1,代码2,符号2,...

  符号个数即以及每个符号分别占8位,每个代码占 log2(符号个数) 向上取整 位。因此,在这个例子中,编码表需要5*8+4*2 = 48 位。压缩比为8000/2048 = 3.9。

  即一段文本的压缩结果是:压缩有的字符串+编码表。

  在字符串aaxuaxz中,a出现3。一个符号出现的次数称为频率frequency. 当不同字符出现的频率有很大差别时,我们可以通过可变长编码来缩短编码串的长度。这带来一个 问题:每次提取多少为代码来解释符号?——只要没有任何一个代码是另一个代码的前缀就可以!因此,当从左到右检查编码位串时,可以得到与一个确切的代码相匹配的字符。

  可以利用扩展二叉树(增加了外部节点的二叉树)来派生一个特殊的类,对具有上述前缀性质的代码,实现可变长编码。这个用于编码的类称为霍夫曼编码。

  在一棵扩展二叉树中,从根到外部节点的路径可用来编码,方法是用0表示向左子树移动一步,1表示向右子树移动一步。我们用S表示待编码字符组成的字符串,F(x)是字符x的出现频率。

  对于一棵具有n个外部节点的扩展二叉树,且外部节点标记为1,2,...,n其对应的编码位串的长度为: WEP = ΣL(i)*F(i)

  L(i)是从根到外部节点i的路径长度(即路径的边数);WEP是二叉树的加权外部路径长度 weighted external path length. 为了缩短编码串的长度,必须使用二叉树代码,二叉树的外部节点与要编码的字符串的字符对应,且WEP最小。一棵二叉树,如果对一组给定的频率,其WEP最小,那么这颗二叉树称为霍夫曼树 Huffman tree。

  用霍夫曼编码对一个一个字符串或一段文本进行编码,需要做的是:

  1.确定字符串的符号和它们出现的频率。

  2.建立霍夫曼树,其中外部节点用字符串中的符号表示,外部节点的权用相应符号的频率表示。

  3.沿着从根到外部节点的路径遍历,取得每个符号的代码。

  4.用代码替代字符串中的符号\






哈夫曼编码数据结构中的一种重要编码方式,具有以下特点和相关信息: ### 性质 - **前缀编码**:哈夫曼编码是前缀编码。它是根到叶子路径上的编码序列,由于的特点,若路径A是另一条路径B的最左部分,则B经过了A,那么A的终点一定不是叶子。而哈夫曼编码对应路径的终点一定为叶子,所以任一哈夫曼码都不会任意其他哈夫曼编码的前缀部分完全重叠[^1]。 - **最优前缀编码**:对于包含n个字符的数据文件,分别以它们的出现次数为权值构造哈夫曼,利用该对应的哈夫曼编码对文件进行编码,能使该文件压缩后对应的二进制文件的长度最短。因为哈夫曼的带权路径长度最短,故字符编码的总长最短[^1][2]。 ### 算法实现 以下是从叶子到根逆向求每个字符的哈夫曼编码的算法实现代码: ```python # 假设这里已经有HuffmanTree和HuffmanCode的定义 def CreateHuffmanCode(HT, HC, n): # 分配n个字符编码的头指针矢量 HC = [None] * (n + 1) # 分配临时存放编码的动态数组空间 cd = [''] * n # 编码结束符 cd[n - 1] = '\0' for i in range(1, n + 1): start = n - 1 c = i f = HT[i].parent while f != 0: # 回溯一次start向前指一个位置 start -= 1 if HT[f].lchild == c: cd[start] = '0' else: cd[start] = '1' c = f f = HT[f].parent # 为第i个字符串编码分配空间 HC[i] = ''.join(cd[start:]) return HC ``` ### 应用优势 通过哈夫曼编码,频率高的字符数据编码长度变短,在处理大量字符时,会大大减少存储率和传输成本。例如原编码二进制串为“000001010011100101”,经过哈夫曼编码后变为“01100110100111000”[^3]。 ### 构建基础 构建哈夫曼哈夫曼编码的基础,根据字符的频率,使用自底向上的方法构建。在构建过程中,将频率最低的两个节点合并为一个新的节点,其频率为两者之和,并将这两个字符分别作为新节点的左右子节点。然后,将新节点加入到未处理的字符列表中,继续重复此过程,直到所有字符都被合并到一个根节点下[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值