Skip to content

算法Algorithm

规范Huffman码与码长表

Canonical Huffman code · 规范赫夫曼码

从带符号的码长表唯一重建码字,以整数空槽检查拒绝过订长度,并逐位解出含EOF的短流。

形式陈述 ​

Huffman算法决定哪些符号获得哪些长度;规范化再决定同样长度下究竟使用哪些bit串。它的输入是有限符号表上的正整数码长 ℓ(s) 和双方约定的符号全序。输出保持每个符号的长度,并满足:短码排在前面;同长度的码是连续二进制整数,按符号顺序分配。规范化没有重新优化概率,也不需要传输原来的左右子树。

记 cb 为长度恰为 b 的符号数,c0=0。最长允许码长为 B;构造每层的首码:

N1=0,Nb=2(Nb−1+cb−1)(2≤b≤B).

对每个长度 b,按符号顺序把 Nb,Nb+1,…,Nb+cb−1 写成恰好 b 位,前面的零不能省略。码字按最高位到最低位发送。

不能拿任意整数表直接移位建表。先验证符号不重复、长度属于 1,…,B,再令 r0=1,逐层计算

rb=2rb−1−cb.

任何一步 rb<0 就拒绝:这一层想放的叶超过可用位置。全部非负时可建成前缀码。rB=0 表示树满,rB>0 表示有未用路径,后者在本页合法。具体标准可以再限制哪些不完整表被接受。

直觉

想象按字典序摆放二叉树的叶。先分配较浅的叶,它的整棵后代就不能再用。进入下一层时,每个剩余空位分裂成两个位置,所以空位数先乘二,再扣掉本层叶数。上面的 rb 是树空间的整数账本,不依赖浮点数近似求和。

首码递推也来自同一动作:长度 b−1 的连续码用完后,紧接着的位置是 Nb−1+cb−1;进入深一层相当于在末尾补零,因此乘二。已占用的浅层子树都落在这条前沿左侧,新码不会落进它们。归纳得到码字互异且没有前缀冲突。

这一证明是Kraft可行性的具体构造。展开递推可得 rB=2B(1−∑s2−ℓ(s))。本页把存在性转成“收到一张表后怎样恢复完全相同的bit映射”,而Huffman旧页继续承担最优性的交换证明。

例子与边界

给五字节 ABABA 加专用结束符EOF,EOF不是正文字符,它的编号为256。字节A、B分别编号65、66,顺序固定为 65<66<256。出现计数为 (3,2,1);合并1和2得到3,再合并两项3,获得长度 (1,2,2)。

于是 c1=1,c2=2;首码 N1=0,N2=(0+1)2=2。结果是 A→0,B→10,EOF→11。发送 A B A B A EOF,有效位为 0|10|0|10|0|11 = 010010011。读者从根开始逐位走,分别在第1、3、4、6、7、9位输出A、B、A、B、A、EOF;末两位是结束符,不能当成正文。

收到长度 (1,1,1) 时,第一层 r1=2−3=−1,建树之前拒绝。长度 (2,2) 则给 00,01,合法但不完整;输入以 1 开始会走进未用区域,应报告非法码流,不能补出一个默认符号。表里两条记录使用相同符号编号也必须拒绝,即使长度的Kraft和不大于一。

空文件仍要结束。本单元规定仅有EOF时给它长度1、码字 0,不采用零长度码。只有一个正文符号A的文件实际有A和EOF两个符号,所以码字为 0,1,可恢复重复次数。本教学文件的码长上限是15;普通Huffman建树若超过15,编码器明确拒绝,不能剪掉高位,也不能宣称自己实现了长度受限Huffman优化。

推论与应用

双方只交换“符号、长度”即可恢复码字,不需要交换每条根到叶路径。若符号表有 m 项,已按符号顺序给出,计数、首码和整数码表的构造需 O(m+B) 次整数操作;若另外输出全部码字字符串,还要支付 Θ(∑sℓ(s)) 位的写出成本。排序未给定的表则另计 O(mlog⁡m)。

规范码经常用于真实压缩格式,但位序属于封装协议。RFC1951的DEFLATE把数据元素放到字节的低位起始位置,Huffman码字自身又按高位先出;本单元的教学文件统一按每字节高位先出,二者不能直接混读。完整表头、结束和填充规则见压缩流封装;检查器还用独立枚举空闲叶的方法检查340张小码长表。

需要保证最大码长时,可以先用package-merge得到保留符号身份的最优限长表,再应用本页同一首码递推。它补足的是选长度的优化步骤;这里已有的正码长、Kraft空槽、符号顺序和物理位序检查不变。既有HUF1编码器仍按其原规则在普通Huffman长度超过15时拒绝,并未隐式切换优化器。

参考资料
  • L. Peter Deutsch,RFC1951,§3.1.1、§3.2.2:位打包与从长度恢复规范码;§3.2.7:动态码表的额外结构约束
  • David A. Huffman,“A Method for the Construction of Minimum-Redundancy Codes”,1952:长度选择的原始最优性算法,见既有Huffman页的完整证明
关系图谱8 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系