【数据结构——哈夫曼树】

本文探讨了哈夫曼树的构建过程,从一个包含4棵小树的森林开始,逐步合并成唯一的哈夫曼树。虽然带权路径长度是唯一的,但树的形态可以因合并次序的不同而变化。我们建议权值较小的节点作为左子树,以促进一致性和有效讨论。

From Here

哈夫曼树 

1. 哈夫曼树的基本概念 
  哈夫曼树( Huffman )又称最优二叉树,是一类带权路径长度最短的树,有着广泛的应用。
  在讨论哈夫曼树之前首先需要弄清楚关于路径和路径长度的概念。树中两个结点之间的路径由一个结点到另一结点的分支构成。两结点之间的路径长度是路径上分支的数目。树的路径长度是从根结点到每一个结点的路径长度之和。 
  设一棵二叉树有 n 个叶子结点,每个叶子结点拥有一个权值W 1 ,W 2 , ...... W n ,从根结点到每个叶子结点的路径长度分别为 L1 , L2......Ln ,那么树的带权路径长度为每个叶子的路径长度与该叶子权值乘积之各。通常记作 WPL = L k. W k 。为了直观其见,在图中把带权的叶子结点画成方形,其他非叶子结点仍为圆形。请看图 6.21 中的三棵二叉树以及它们的带权路径长。

(a) wpl=38 (b) wpl=49 (c) wpl=36 图 6.21 具有不同带权路径长度的二叉树 
注意:
这三棵二叉树叶子结点数相同,它们的权值也相同,但是它们的 wpl 带权路径长各不相同。图 6.21(c)wpl 最小。它就是哈曼树,最优树。哈夫曼树是,在具有同一组权值的叶子结点的不同二叉树中,带权路径长度最短的树。也称最优树。 
2. 哈夫曼树的构造 
构造哈夫曼树的方法 
对于已知的一组叶子的权值W 1 ,W 2...... ,W n 
①首先把 n 个叶子结点看做 n 棵树(仅有一个结点的二叉树),把它们看做一个森林。 
②在森林中把权值最小和次小的两棵树合并成一棵树,该树根结点的权值是两棵子树权值之和。这时森林中还有 n-1 棵树。 
③重复第②步直到森林中只有一棵为止。此树就是哈夫曼树。现给一组 (n=4) 具体的权值 2 , 4 , 5 , 8 ,下边是构造具体过程: 

图 6.22 哈夫曼树构造过程 

图 6.22(a) 是一个拥有 4 棵小树的森林,图 6.22(b) 森林中还有 3 子棵树,图 6.22(c) 森林中剩下 2 棵树,图 6.22(d) 森林只有一棵树,这棵树就是哈夫曼树。这里或许会提出疑问, n 个叶子构成的哈夫曼树其带权路径长度唯一吗?确实唯一。树形唯一吗?不唯一。因为将森林中两棵权值最小和次小的子棵合并时,哪棵做左子树,哪棵做右子树并不严格限制。图 6.22 之中的做法是把权值较小的当做左子树 , 权值较大的当做右子树。如果反过来也可以,画出的树形有所不同,但 WPL 值相同。为了便于讨论交流在此提倡权值较小的做左子树 , 权值较大的做右子。

哈夫曼编码是数据结构中的一种重要编码方式,具有以下特点和相关信息: ### 性质 - **前缀编码**:哈夫曼编码是前缀编码。它是根到叶子路径上的编码序列,由于的特点,若路径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、付费专栏及课程。

余额充值