在手动计算时,对哈夫曼编码的流程还是非常熟悉的,所以难点就是代码实现。在实现以前,我考虑了以下一些问题:一个符号的哈夫曼编码值可以用一个向量进行存储,符号合并以后的结果用什么表示,对其赋值0,1如何作用在被合并的原始符号上面。由于哈夫曼编码是从树根开始,存在继承上一节点编码的现象,故要与手动计算的方向相反,先根据概率及其合并得出各层次之间的关系,然后从底层向上开始编码。
编码中用到的一个核心函数是sort函数,用法如下:
[B,I]=sort(A)
如果 A=[5 4 7 0 2 ]
B=[0 2 4 5 7]
I=[4 5 2 1 3]是排序以后的数在原序列中的位置
以输入概率P=[0.2 0.15 0.4 0.25]为例对编码思路进行分析。
每经过一次合并,排序的概率少一个,最终由n个变成2个。为此可开辟一个n-1行 n*n列的编码矩阵c,第一行是对n个符号进行编码,直到n-1行是对2个符号进行编码。上一层编码是在下一层的基础上增加0或1 但是是在下一层哪个编码的基础上增加呢,这就要知道概率和是由原来的哪两个概率就和得到的。//为解决这个问题,需要用到sort()函数返回I的用法(上文提到的)。构建n-1行n列的合并关系矩阵m,与编码矩阵相对应。m矩阵对应位置的值就是指编码矩阵中该位置在排序前是在哪一位。
由于哈夫曼编码的不唯一性,规定概率小编码0,大的编码1。
生成m矩阵
红框中3的含义是:四个符号按概率从小到大进行排序,将概率较小的两个合并,变成三个符号。这三个符号进行新的排序以后,该位置上的符号是原始序列的第三个。
下面是代码及其详细解释:
p=[0.2 0.15 0.4 0.25]
%判断信源的合理性
if length(find(p<0))~=0
error('错误!出现小于0的概率')
end
if abs(sum(p)-1)>10e-10
error('错误!信源不满足完备性')
end
n=length(p);
q=p;
%构建概率合并关系矩阵
m=zeros(n-1,n);
for i=1:n-1