哈夫曼编码是一种无损数据压缩算法,该算法在数据压缩,存储和网络传输等领域广泛引用,对互联网的发展也产生了深远的影响。
大家熟知的数据无损压缩软件,如WinRAR,gzip,bzip,lzw,7-zip等,都应用了哈夫曼算法。
广泛使用的PNG,JPEG,WebP图像格式,MP3音频格式,H.264(AVC)和H.265(HEVC)视频编码标准,都应用了哈夫曼编码。
1. 在传递信息时,如何尽量节省空间并保证无损编译?
如果要用01编码向某向某人传递信息,并要求尽可能节省空间且数据无损坏,要如何进行设计与实现?
我们已经了解过ASCLL这种编码方式了,对于每一种字符,我们用等长的八位二进制编码对其进行表示。
但是,当我们需要用到的字符较少时,每个字符都使用八位二进制来进行编码就会浪费很多空间。
那么,我们要如何设计一种编码方式来针对特定的情况进行编码呢?
1.1 等长编码
假设我们要传递的信息是单词“success”。
我们的第一种思路依然是采用等长的二进制序列来进行编码,但是,针对特定情况,我们可以采用较少的二进制位来编码。
对具体情况进行分析,我们发现,success中只有四种字符(s,u,c,e),于是我们只需要用2位二进制便可编码:
字符 | s | u | c | e |
编码 | 00 | 01 | 10 | 11 |
依据此编码方式,我们可以将success转化为二进制序列“00011010110000”。
在解码时,只需对照编码表,每二位一译即可无损译出“success”。
该种编码方式,相对于用ASCLL码来编译节省了许多的空间,并且做到了无损译码。
但是,还能节省更多空间吗?
1.2 变长编码
在刚才的例子中,我们经过思考我们找到一种思路:出现频率高的字符,采用较短的编码。
简单分析会发现,success中,s出现了3次,c出现了2次,e和u各一次。
于是我们可以采用以下这种编码方式:
字符 | s | c | e | u |
编码 | 0 | 1 | 01 | 11 |
依据此编码方式,我们可以将success转化为二进制序列“011110100”。
相比于刚才总长14位的二进制编码,这次我们仅用了9位二进制就表示出了“success”,压缩率达到64%。
但是,变长编码在解决长度问题的同时,又导致无损编码成为了问题。
例如,在解码的过程中,我们可以有这些不同的方式来理解所接收到的信息: