哈夫曼树(最优二叉树)

1 用途

现在假如有一个需求, 把一个很长的字符串用二进制编码的形式存储, 要尽可能的占用较小空间, 那么应该怎么存储呢. 肯定是要确定每个字母的编码方法, 比如 001是A, 010是B等. 那么要怎么确定每个字符编成什么二进制码从而使得总长度最短? 一个根本思想是, 出现频率高的字母尽量编码短一些, 出现频率少的字符长一些. 这样就需要有一种方法去确定每个字符的二进制编码的方法, 需要构建一棵树 --- 哈夫曼树.

2 方法

举个例子, 现有一个字符串, 其中所有字符出现频率如下:

A: 60, B: 45, C: 13 D: 69 E: 14 F: 5 G:3

1. 把字符频率表按照频率从大到小排序

排序如下:

D: 69, A: 60, B: 45, E: 14, C: 13, F: 5, G:3

2. 把当前字符频率表的最后两个取出, 作为兄弟节点构建成二叉树, 其规则为: 频率小在左, 二者父节点为二者频率之和

取出目前频率最小的两个节点: F和G, 如图所示:

3. 把二者作为一个元素重新放入频率表(频率表还是要按照频率排序)

此时为:

D: 69, A: 60, B: 45, E: 14, C: 13, FG:8

4. 重复23步, 直至所有构建哈夫曼树完成

此时最后两个元素为C: 13和FG: 8, FG在左, C在右:

更新频率表:

D: 69, A: 60, B: 45, CFG:21, E: 14

选择E和CFG构建:

更新频率表:

D: 69, A: 60, B: 45, CFGE: 35

选择B和CFGE构建:

更新频率表:

BCFGE: 80, D: 69, A: 60

选择D和A构建:

更新频率表:

DA: 129, BCFGE: 80

选择DA, BCFGE构建, 完成:

把所有边按照左0右1进行标注:

将每个字符, 按照从根节点到其的所有边的码连接起来, 就是每个字符的编码. 对应如下:

A: 10

B: 01

C: 0011

D: 11

E: 000

F: 00101

G: 00100

这样, 利用哈夫曼树来进行字符串编码就完成了.

那么, 为什么能够保证一大长串的二进制码解析出来的是唯一的呢, 首先思考, 什么情况会导致我们解析现有编码会有多种选项呢? 假如当前正在解析二位码01, 此时已经有对应的字母了, 但是发现011或者010还可以解析成另一个字符, 这样就会有多种解码方法, 但是会发现, 哈夫曼树额每个字符都在叶节点上, 也就是说01如果对应了字符, 就不会存在010或者011也为字符的情况, 从而消除了多重解码的困惑.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值