[转载]Huffman编码压缩算法
转自http://coolshell.cn/articles/7459.html
前两天发布那个rsync算法后,想看看数据压缩的算法,知道一个经典的压缩算法Huffman算法。相信大家应该听说过 David Huffman 和他的压缩算法—— Huffman Code,一种通过字符出现频率,Priority Queue,和二叉树来进行的一种压缩算法,这种二叉树又叫Huffman二叉树 —— 一种带权重的树。从学校毕业很长时间的我忘了这个算法,但是网上查了一下,中文社区内好像没有把这个算法说得很清楚的文章,尤其是树的构造,而正好看到一篇国外的文章《A Simple Example of Huffman Code on a String》,其中的例子浅显易懂,相当不错,我就转了过来。注意,我没有对此文完全翻译。
我们直接来看示例,如果我们需要来压缩下面的字符串:
“beep boop beer!”
首先,我们先计算出每个字符出现的次数,我们得到下面这样一张表 :
| 字符 | 次数 |
| ‘b’ | 3 |
| ‘e’ | 4 |
| ‘p’ | 2 |
| ‘ ‘ | 2 |
| ‘o’ | 2 |
| ‘r’ | 1 |
| ‘!’ | 1 |
然后,我把把这些东西放到Priority Queue中(用出现的次数据当 priority),我们可以看到,Priority Queue
是以Prioirry排序一个数组,如果Priority一样,会使用出现的次序排序:下面是我们得到的Priority Queue:

接下来就是我们的算法——把这个Priority Queue
转成二叉树。我们始终从queue的头取两个元素来构造一个二叉树(第一个元素是左结点,第二个是右结点),并把这两个元素的priority相加,并放
回Priority中(再次注意,这里的Priority就是字符出现的次数),然后,我们得到下面的数据图表:

同样,我们再把前两个取出来,形成一个Priority为2+2=4的结点,然后再放回Priority Queue中 :

继续我们的算法(我们可以看到,这是一种自底向上的建树的过程):



最终我们会得到下面这样一棵二叉树:

此时,我们把这个树的左支编码为0,右支编码为1,这样我们就可以遍历这棵树得到字符的编码,比如:‘b’的编码是 00,’p'的编码是101, ‘r’的编码是1000。我们可以看到出现频率越多的会越在上层,编码也越短,出现频率越少的就越在下层,编码也越长。

最终我们可以得到下面这张编码表:
| 字符 | 编码 |
| ‘b’ | 00 |
| ‘e’ | 11 |
| ‘p’ | 101 |
| ‘ ‘ | 011 |
| ‘o’ | 010 |
| ‘r’ | 1000 |
| ‘!’ | 1001 |
这里需要注意一点,当我们encode的时候,我们是按“bit”来encode,decode也是通过bit来完成,比如,如果我们有这样的
bitset “1011110111″ 那么其解码后就是 “pepe”。所以,我们需要通过这个二叉树建立我们Huffman编码和解码的字典表。
这里需要注意的一点是,我们的Huffman对各个字符的编码是不会冲突的,也就是说,不会存在某一个编码是另一个编码的前缀,不然的话就会大问题了。因为encode后的编码是没有分隔符的。
于是,对于我们的原始字符串 beep boop beer!
其对就能的二进制为 : 0110 0010
0110 0101 0110 0101 0111 0000 0010 0000 0110 0010 0110 1111 0110 1111
0111 0000 0010 0000 0110 0010 0110 0101 0110 0101 0111 0010 0010 0001
我们的Huffman的编码为: 0011 1110 1011 0001 0010 1010 1100 1111 1000 1001
从上面的例子中,我们可以看到被压缩的比例还是很可观的。
作者给出了源码你可以看看( C99标准) Download the source files
[转载]Huffman编码压缩算法的更多相关文章
- Huffman 编码压缩算法
前两天发布那个rsync算法后,想看看数据压缩的算法,知道一个经典的压缩算法Huffman算法.相信大家应该听说过 David Huffman 和他的压缩算法—— Huffman Code,一种通过字 ...
- huffman编码压缩算法(转)
参考:http://blog.csdn.net/sunmenggmail/article/details/7598012 笔试时遇到的一道题.
- huffman 编码
huffman压缩是一种压缩算法,其中经典的部分就是根据字符出现的频率建立huffman树,然后根据huffman树的构建结果标示每个字符.huffman编码也称为前缀编码,就是每个字符的表示形式不是 ...
- Huffman编码实现压缩解压缩
这是我们的课程中布置的作业.找一些资料将作业完毕,顺便将其写到博客,以后看起来也方便. 原理介绍 什么是Huffman压缩 Huffman( 哈夫曼 ) 算法在上世纪五十年代初提出来了,它是一种无损压 ...
- [老文章搬家] 关于 Huffman 编码
按:去年接手一个项目,涉及到一个一个叫做Mxpeg的非主流视频编码格式,编解码器是厂商以源代码形式提供的,但是可能代码写的不算健壮,以至于我们tcp直连设备很正常,但是经过一个UDP数据分发服务器之后 ...
- Huffman编码
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstdio> #include <cstri ...
- 【数据压缩】Huffman编码
1. 压缩编码概述 数据压缩在日常生活极为常见,平常所用到jpg.mp3均采用数据压缩(采用Huffman编码)以减少占用空间.编码\(C\)是指从字符空间\(A\)到码字表\(X\)的映射.数据压缩 ...
- 优先队列求解Huffman编码 c++
优先队列小析 优先队列的模板: template <class T, class Container = vector<T>,class Compare = less< ...
- Huffman编码实现电文的转码与译码
//first thing:thanks to my teacher---chenrong Dalian Maritime university /* 构造Huffman Tree思路: ( ...
随机推荐
- Python开发【模块】:M2Crypto RSA加密、解密
M2Crypto 模块 快速安装: # 环境centos7.0,提前装好openssl(自行百度安装),windows装不上,暂不考虑了 [root@localhost ~]# pip install ...
- SQL和access随机数
Access: CLng(Rnd(种子数字)*1000000) SQL Server ceiling(rand(abs(checksum(newid())))*1000000)
- Linux常用命令【总结】
Linux命令中文版详解:https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/index.html Linux系统,我用过的有centos和 ...
- 用nginx的反向代理机制解决前端跨域问题在nginx上部署web静态页面
用nginx的反向代理机制解决前端跨域问题在nginx上部署web静态页面 1.什么是跨域以及产生原因 跨域是指a页面想获取b页面资源,如果a.b页面的协议.域名.端口.子域名不同,或是a页面为ip地 ...
- Spark Streaming带状态更新
带状态的更新是使用的updateStateByKey方法,里面传入一个函数,函数要自己写,注意需要设置checkpoint import org.apache.spark.streaming.kafk ...
- 通过IP地址和子网掩码与运算计算相关地址
通过IP地址和子网掩码与运算计算相关地址 知道IP地址和子网掩码后可以算出 网络地址 广播地址 地址范围 本网有几台主机 例一:下面例子IP地址为192.168.100.5 子网掩码是255.255. ...
- OA项目_环境搭建
OA项目现在要做成微服务,用的框架是springboot,所用的编程工具是idea,maven,做为一个程序员最关心的就是我需要在那个架包中编写代码,我们只需关注domain,repository,s ...
- 已有模板与tp框架的结合 (前台)
已有模板与tp框架的结合 具体步骤 A.复制模板文件到view指定目录 B. 复合css .js.img.静态资源文件到系统指定目录 C. 把静态资源(css,js,img)文件的路径设置为“常量 ...
- 手游精品时代,iClap参会TFC高效解决手游问题
随着“互联网+”概念的广泛应用,文娱类产品跨界融合的现象日益明显,不再以孤立的形态出现在市场中.移动游戏作为泛娱乐产业链的变现末端和关键环节,在传统游戏和VR/AR.HTML5.机器人.智能设备等新业 ...
- 2016-2017 ACM-ICPC CHINA-Final Solution
Problem A. Number Theory Problem Solved. 水. #include<bits/stdc++.h> using namespace std; ; typ ...