赫夫曼编码是我们经常使用的一种类型编码,它是一种即时码,有很多优点,下面我们使用matlab语言来实现huffman编码的过程。
首先,我们输入一组概率,这里以[0.512 0.128 0.128 0.032 0.128 0.032 0.032 0.008]为例。
P=[0.512 0.128 0.128 0.032 0.128 0.032 0.032 0.008];%输入
l=length(P);
n=2*l-1;%节点总个数
并计算需要的节点数。
接着我们定义编码结果元胞,来记录一些信息。
cell=zeros(n,5);%节点,有编号、概率、分配的码元、组成1、组成2.
接着初始化元胞
for i=1:l
cell(i,:)=[i,P(i),3,0,0];%3,0,0是坏值
end
for i=l+1:n
cell(i,:)=[i,0,3,0,0];
end
上面的cell元胞是最终结果,而参与运算的是当前运算元胞,不是cell,我们来定义当前运算元胞
%初始化当前考虑点
ce=cell(1:l,:);
接着是运算的具体机制:
for i=1:l-1%一共有n-1次合并
ce=sortrows(ce,2);%按概率从小往大排序
ce(size(ce,1)+1,:)=[l+i,ce(1,2)+ce(2,2),3,ce(1,1),ce(2,1)];
cell(l+i,:)=[l+i,ce(1,2)+ce(2,2),3,ce(1,1),ce(2,1)];
%小0,大1
id1=find(cell(:,1)==ce(1,1));
cell(id1,3)=0;%分配码元
id2=find(cell(:,1)==ce(2,1));
cell(id2,3)=1;%分配码元
ce(1,:)=[];%删除用掉的
ce(1,:)=[];%删除用掉的
end
cell(end,:)=[];%删除最后一个
这里我们就得到了最终的结果,如下图:
但是为了方便观察每个码字的具体编码情况,我们增加一个步骤来将cell变成编码:
%将cell翻译成编码
code=4*ones(l,l);
for i=1:l
flag=i;%标签
k=1;%记录码长
code(i,k)=cell(i,3);%第一个码字
id1=find(cell(:,4)==flag);
id2=find(cell(:,5)==flag);
if length(id1)==1
id=id1;
elseif length(id2)==1
id=id2;
else
id=0;
end
while(id~=0)
k=k+1;%码长加一
code(i,k)=cell(id,3);
flag=id;
id1=find(cell(:,4)==flag);
id2=find(cell(:,5)==flag);
if length(id1)==1
id=id1;
elseif length(id2)==1
id=id2;
else
id=0;
end
end
end
编码的结果如图:
数字4代表没有使用的位置
最后,我们计算平均码长:
%计算平均码长
sum=0;
for i=1:l
L=length(find(code(i,:)~=4));
sum=sum+P(i)*L;
end
全部代码,见资源:赫夫曼Huffman编码.rar
https://download.csdn.net/download/weixin_43102634/11939982