代码
function [ u, c, e, f] = huff_codec( A ) %HUFF_CODEC 哈夫曼编码的MATLAB实现 % author==Frank % 本程序重点在建树和建表过程,以及求解平均码长和编码效率 % 因为建表的顺序不一致,可能会导致码表不一致,但是都满足熵编码要求 %u 输出排序后的频率分布 %c 输出码表 %e 输出平均码长 %f 输出编码效率 平均码长/熵 %A 输入的原始频率分布,为行向量eg A=[1,2,3,4,5] A=sort(A,'descend');%按降序排列 T=A;u=A; A=A/sum(A); [~,n]=size(A); %生成待编码矩阵,每列最后一个元素为特殊元素的位置 B=zeros(n,n); for i=1:n B(i,1)=T(i);%生成编码表的第一列 end r=B(i,1)+B(i-1,1);%最后两个元素相加 T(n-1)=r;T(n)=0; T=sort(T,'descend'); t=n-1; for j=2:n%生成编码表的其他各列 for i=1:t B(i,j)=T(i); end if t>1 K=find(T==r); B(n,j)=K(end);%从第二列开始,每列的最后一个元素记录特征元素在该列的位置 r=(B(t-1,j)+B(t,j));%最后两个元素相加 T(t-1)=r; T(t)=0; T=sort(T,'descend'); t=t-1; else B(n,j)=1; end end %生成Huffman码字矩阵和排序后元素的码表向量 m=3;s1=sym('[2,1]');s2=s1;%码表,用1表示0,2表示1,因为0会因为被省略导致无法记录 %这里意思是从倒数第三列开始建表,因为最后一列和倒数第二列的情况我们可以直接推出。 for i=n-2:-1:1 p=B(n,i+1);%p是每列保存的特殊元素的位置,特殊元素指的是由上一列最后两个数新合成的数 if p==1 s2(1:m-2)=s1(2:m-1); elseif p==m s2(1:m-2)=s1(1:m-2); elseif p==2 s2(1)=s1(1); s2(2:m-2)=s1(3:m-1); else s2(1:p-1)=s1(1:p-1); s2(p+1:m-2)=s1(p+1:m-2); end s2(m-1)=[char(s1(p)),'2']; s2(m)=[char(s1(p)),'1']; m=m+1; s1=s2; end L=zeros(1,n); for i=1:n [~,r]=size(char(s2(i))); L(i)=r; end %将码表转换成0和1输出 arr=zeros(1,n); arr(1:n)=s2(1:n); str=[]; for i=1:n s=num2str(arr(i)); s=strrep(s,'1','0'); s=strrep(s,'2','1'); if i==1 str=s; else str=[str,' ',s]; end end str=regexp(str,' ','split'); %计算返回值 c=str; e=sum(L.*A);%平均码长 H1=log2(A); H=-A*(H1');%熵 f=H/e;%编码效率 end
使用示例
>>p=[1,2,3,4,5,6,7] >>[ u, c, e, f] = huff_codec( p )
参考
matlab实现huffman编码
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/214465.html原文链接:https://javaforall.net
