MATLAB编程实现哈夫曼编码

用MATLAB编程实现哈夫曼编码

一.实验目的

  • 理解信源编码的意义
  • 熟悉 MATLAB程序设计;
  • 掌握哈夫曼编码的方法及计算机实现

二.实验原理

  • 统计n个信源消息符号,得到n个不同概率的信息符号
  • 将这n个信源信息符号按其概率大小依次排序:
    p(x1) ≥ p(x2)≥ …≥ p(xn)
  • 取两个概率最小的信息符号分别配以0和1两个码元,并将这两个概率相加作为一个新的信息符号的概率,和未分配的信息符号构成新的信息符号序列
  • 将剩余的信息符号,按概率大小重新进行排序
  • 重复步骤3,将排序后的最后两个小概论相加,相加和与其他概率再排序。
  • 如此反复重复n-2次,最后只剩下两个概率
  • 从最后一级开始,向前返回得到各个信源符号所对应的码元序列,即相应的码字,构成霍夫曼编码字。编码结束

三.代码编写

a=rand(1,10);    %利用rand函数生成一10维随机向量 
b=norm(a,1);     %对向量a的各个元素进行累加求和
a=a/b;           %将随机向量a进行归一化
y=8*ones(10);    %初始编码表,y为10*10的元素全为8的矩阵
t=ones(10,1);    %t为10*1的矩阵,元素全为1
z=zeros(9,10);   %z为9*10的零矩阵
x=a;             %x为向量a归一化后的向量
for k=1:9
 x=sort(x);       %将x中的值按从小到大的顺序排序,得到新的x
p=find(a==x(1));       %找到向量a中最小元素(概率)的下标
q=find(a==x(2));
   if (size(p))        %该if-else命令的判断依据是什么? 如果矩阵p不为空则执行if语句后面代码,如果矩阵p为空则执行else语句后的代码
       y(p,t(p))=1     %y矩阵的第p行第t(p)列变为1,小概率编码为1
       t(p)=t(p)+1     %t的第p行元素加1
       z(k,2)=p        %将z矩阵第k行第2列元素赋值为概率小元素下标
       i=3             %y,t,z的值分别发生了什么变化?
   else
      [s,w]=find(z==x(1))  
%s,w分别是z中元素等于x(1)的元素的位置,s为行,w为列
       i=2;
       while(z(s,i)>0)      %整个while循环的作用是什么?
           p=z(s,i)        %找到新合成的概率来自于哪两个信源符号
%并给他们配以1码元
           z(k,i)=p
           y(p,t(p))=1
           t(p)=t(p)+1
           i=i+1;
       end  
   end
                         %上面的if-else是对信息符号最小的配以1码元
if(size(q))                 %下面if-else是对信息符号第二小的配以0码元
    y(q,t(q))=0
    t(q)=t(q)+1
    z(k,i)=q
  else
    [s,w]=find(z==x(2))
    r=2
    while(z(s,r)>0)
        q=z(s,r)
        z(k,i)=q
        y(q,t(q))=0
        t(q)=t(q)+1
        i=i+1
        r=r+1
    end
  end
b=[x(1)+x(2)]
z(k,1)=x(1)+x(2)
%为什么是3到11-k?
%k=1为例 x(1)与x(1)合并为一个新概率,矩阵b初始只有新合成的这个概率
%还需要把x(3)到x(10)八个概率加入,形成更新一次更新后的概率矩阵
   for i=3:(11-k)           
     b=[b,x(i)]             
   end                    
x=b
end

for i=1:10          %循环输出每个信源符号的哈弗曼编码
    n=[]
    for r=t(i)-1:-1:1
        n=[n,y(i,r)] 
    end                %输出为整型数据,格式如下
    fprintf('a%d',i)   %a1  字符编码
    disp(n)            %a2  字符编码
end                    %……
                       %ai  字符编码
                       %……
                       %a10 字符编码
z=0;
for i=1:10                 %计算平均码长
z=z+a(i)*(t(i)-1)
end
 fprintf('z=%f',z)       %输出为float型数据,小数点后保留6位
%% 自己编制函数,计算平均码长与编码效率
HX=sum(a.*(-log2(a)));    %计算信源熵
yita=HX/z;                %计算编码效率
rr=1-yita;                %计算冗余度

希望各位小伙伴们一起学习,共同进步,加油!

你可能感兴趣的:(matlab,算法,霍夫曼树)