贪心算法(Greedy Algorithm)之霍夫曼编码(Huffman codes)

其实这个霍夫曼编码本身不是一个很难的技巧(也是霍夫曼在期末考试的过程中想出来的方案:)),因为中间用到了贪心的思想,所以也在这里列举了出来。这个问题本身在计算机系的很多教材上都出现过。这里权且记录下来。

霍夫曼的编码是这样的。假设我有一组带压缩的文本,里面各个字符出现的频率不同,现在需要对他们进行压缩。比如

image

假设我们有100,000个字符的文本.最直观的压缩办法就是原来每个字符要8个bits。现在我一共只有6个字符,那我就把每个字符用3个二进制 位来表示,这样所有100,000个字符用300,000个bit就可以表示了。这种是最直观的方案。但是霍夫曼提出的方案更精妙一些。他提出,基于每个 字符出现的频率不同,可以让出现次数多的字符用更少的二进制位来描述,出现次数少的字符用多一些二进制来描述。比如上图显示的这个Variable- length codeword里面。a出现的频率最高,所以用一个二进制位0来表示。而f出现的频率很小,所以用4个二进制位来表示。这样总共 (45 · 1 + 13 · 3 + 12 · 3 + 16 · 3 + 9 · 4 + 5 · 4) · 1,000 = 224,000 bits。可以看到这个是比原来的方案更优化的解法。

我们一样的还是用一张图来描述霍夫曼编码的流程:

image2

这个过程概括的说就是一个根据频率建立二叉树的过程。建完之后对应的编码也就完成了。

第一步a. 这个a就和之前的活动选择问题一样,把需要的所以字符按照频率排序。

第二部b. 选取出现频率最小的两个节点 f 和 e。组成一个新的节点,新的节点的频率就是e和f的和。原来的e和f分别成了新节点的左子节点和右子节点。(注意这里一个默认的规则就是频率小的是左子节 点,大的是右子节点。)然后把之前的两个节点从原来的组中删除,加新的节点加入排序。

第三部c. 其实和第二部雷同,就是一个循环的过程。这里再次去除队列中的最小频率的两项(这时是c和b)。组成新的节点加入队列排序。

如此循环往复,最后就形成了(f)这个二叉树。现在有了二叉树只有,我们把左子树这条边标记为0,右子树标记为1。这样就差生了对应的编码方式 a=0; b=101;....

下面是对应的代码:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值