在计算机中,是用二进制码来表示字符的,比如我有A, B, C, D四个字符,4个字符2位就可以表示了。如可以把A表示为00,B为01,C为10,D为11。在进行数据传输的时候,若有100个这样的字符,那么就需要传输200位,能不能想办法让传输的位数少点呢。
有人就想出了前缀码,根据统计的规律,字母A出现的概率为50%,字母B出现的概率为25%,字母C出现的概率为20%,字母D出现的概率为5%。那么我们如果使用一种变长的编码方案,把概率高的字符编码时位数安排少点。这样我们就想,A编码为0,B编码为0,C编码为10,D编码为11,哈哈,这样就少很多了,看一下期望值:
A: 100*0.5*1
B: 100*0.25*1
C: 100*0.2*2
D: 100*0.05*2
总共是125,而原先是200少了很多。
带来的新的问题
但是也带来了新的问题,以前发送端发送一串字符如ABCD(00011011)时,接收端把每两位解码为相应的字符。但是现在ABCD表示为011011,那么接收端就无法识别了,不知道到底读1位解析还是读二位,如这里的C(10),那也可以解析为BA。为了能够尽可能的减少发送的位数,同时又方便接收端识别,就有了前缀码。
前缀码定义:
在对字符进行二进制编码时,任意字符的编码都不是其他字符编码的前缀。就是说不可能出现A的编码为0,而C的编码是以0开头的,如01,001这样。
实际举例:
在设计中,比如ABCD的编码分别为,0,10,110,111,那么aabcbd的编码为0010110101出现11,接收端在收到这串编码后,看到0,立马转为A,然后又是一个A,接下来是收到1,那么就知道会在BCD里选,要看下一位,再收到0,就知道是B了,一直这样下去直到解析完成。
发现可以利用二叉树来构造前缀码,而具有最优前缀编码的树叫做哈夫曼树
出现概率比较高的字母应该用较少的编码位数,对应的在树中的位置应该比较接近根。