算法设计——哈夫曼编码(贪心算法)

问题

已知一组字符的频率,求其哈夫曼编码

即构造一棵哈夫曼树(字符均在叶子节点上)
如果使用固定编码会导致空间浪费,所以用哈夫曼编码减少浪费

分析

平均传输位数B=∑(字符出现的频率fX字符所在的叶子在书中的深度d)
我们要使平均传输位数最小,那么我们就需要构建哈夫曼树

哈夫曼树:每次从已知频率中选择频率最小的两个进行构建,使用了频率最小的后需要将两频率和加起来放在已知中,同时删除使用过的频率

最优前缀码性质

引理1: C是字符集,∀c∈C, f©为频率, x, y∈C, f(x), f(y) 频率最小, 那么存在最优二元前缀码使得x, y 码字等长且 仅在最后一位不同

算法设计——哈夫曼编码(贪心算法)_第1张图片
因为f(a)>=f(x),所以B(T’)<=B(T)
同理可得B(T’’)<=B(T’)
得到B(T’’)<=B(T’)<=B(T)
但是T是最优解,那么有B(T)<=B(T’’)
由此得到B(T)=B(T’’) 此时f(a)=f(x),f(b)=f(y)
因此最有前缀码具有贪心选择性质

引理2:设T是二元前缀码的二叉树,∀x, y∈T , x, y是树叶 兄弟,z 是x, y的父亲, 令T’ =T−{x, y} ,且令z 的频率 f(z) = f(x)+f(y) T’是对应二元前缀码 C’ = (C−{ x, y })∪{ z } 的二叉树,那么 B(T)=B(T’)+f(x)+f (y)
证明过程:
B(T)=∑(f(C)Xd(C))
B(T’)=∑(f(C’)Xd(C’))
B(T’)=∑(f(C’-{z})Xd(C’-{z}))+f(z)Xd(z)
B(T’)=∑(f(C’-{z})Xd(C’-{z}))+(f(x)+f(y))X(d(x)-1)
B(T’)=∑(f(C’-{z})Xd(C’-{z}))+f(x)Xd(x)+f(y)Xd(x)-f(x)-f(y)
B(T’)=B(T)-f(x)-f(y)
得到:B(T)=B(T’)+f(x)+f (y)
引理2证明了构造最优前缀码的问题具有最优子结构性质

算法正确性证明

含有n个字符的集合
归纳基础证明:对于n=2的字符集, Huffman算法得到最 优前缀码.
n=2,字符集C={x1, x2},对任何代码的字符至少都需要1位二 进制数字. Huffman算法得到的代码是0 和1,是最优前缀码.

归纳步骤证明:假设Huffman算法对于规模为k 的字符集 都得到最优前缀码,那么对于规模为k+1的字符集也得到 最优前缀码.
假设k个字符的集合C都得到最优前缀码
C’=C+{k+1},x1,x2是C’中频率最小的两个字符
设C’’={C’-{x1,x2}}∪{z},fz=fx1+fx2
得到一棵关于字符集C’’, 频率f(z)和f(xi) (i =3,4, …,k+1)的最优前缀码的二叉树T’,把x1,x2作为z 的儿子附到T’上,得到树T,那么T是关于C=(C’ -{z})∪{x1, x2} 的最优前缀码的二叉树. 如若不然, 存在更优树T*, B(T*)中x1和x2 ,得到T’. 根据引理2
B(T*’)=B(T*)-f(x)-f(y) 与T’是一棵关于C’的最优前缀码的二叉树矛盾

算法设计——哈夫曼编码(贪心算法)_第2张图片

你可能感兴趣的:(算法设计,贪心算法)