在了解哈夫曼编码之前先了解一下什么是编码,编码简单来说就是将某个东西对应成另外一个东西,这样的一种对应关系就叫编码,可以想到初中高中所学的函数,给出一个x,对应一个Y,当然编码是一种单射,一个x只能对应一个y,一个y也只能被一个x对应,像我们的函数,x=1的时候,y=1,x=-1的时候,y也等于1,这样就不行。
ASCII码:像我们常见的ASCII码就是一种编码方式,他将各种符号对应到0到128,当然128后面也留着有备用。比如我们的字母A,ASCII码是65,二进制就是0100 0001。需要注意的是ASCII是一种定长编码(编码长度固定,像ascii码二进制都是8位),
哈夫曼编码:与ASCII不同,哈夫曼编码是一种可变长编码,他的编码长度可以变化,比如字母A,在哈夫曼编码里可能就会是100 0001,只有七位,前面少了一个没有作用的0。
那哈夫曼编码是如何将数据对应的呢?我们以一串字母 ACBACBBCBBDC为例,假设我们要传给别人这样一串字母,一共12个字母,如果是ASCII码,那就需要96位大小。
那哈夫曼是先将字母出现次数统计一下,A-2.B-5,C-4,D-1.然后算出他们各自出现的概率,通过概率大小来编码(由于概率数字有分数小数,我们这里就以次数多少来编码举例,实际效果一样)。
按照我们平时,可能会想,我直接A对应0,B对应1,C对应2,D对应3这样编码就可以了,定长的话,每个都是两位大小。A是00,B是01,C是10,D是11。这样12个字母只要24位就可以了,但是还可以更少,那就是不定长,也就是可变编码,这样的话A是0,B是1,C是10,D是11,这样的话,这12个字母就只要2+5+8+2=17位大小了,但这样又会出现一个问题。
按照刚才假设来编码,那12个字母编码就会是0 10 1 0 10 1 1 10 1 1 11 10,但因为这些数字都是连在一起的,比如第三个和第四个字母BA,编码是1 0就有可能误认为是C,而第二个字母C又有可能误认为是BA。
那我们看一下哈夫曼是怎么处理这些问题的,首先将字母按照出现次数排序为,DABC。
然后将最少的两个结合, DA 结合,那么他们的组合次数相加是3,
再次两个最小的结合,这时最小的是AD组合,和C,那么他们两个结合
这时候,剩下CAD这个组合和B,再次结合
最后给每根线标上号码,
这样就得到各个字母的编码,B是0,C是10,A是110,D是111,这样12个字母的编码就只要
5+8+6+3=22位,这样比定长编码位数少,同时又确保了不会出现混淆的情况。刚才会出现混淆的情况是因为有些编码可以由其他编码组合得到,比如刚才的B是1,A是0,C是10。
当然不是说哈夫曼编码就比ASCII好,各种编码自有其优劣性。
比较:
定长编码:
优点:长度固定,容易区分每个元素,(固定多少位是一个元素,如上述定长编码A是00,B是01,那么0001,可以直接算出前面两位表示00,从而判断出对应元素是A)
缺点:位数消耗更多,同样的位数,传递的信息更少
变长编码:
优点:位数消耗少,同样的位数,传递信息更多
缺点:长度不固定,在判断数字对应的元素时需要先判断由多少位组成某个元素。(如按照上述哈夫曼编码,11010,第一个元素的编码需要先判断出由三位组成,然后算出是110,再判断出是C)