Huffman編碼m檔案分析

stone1566發表於2008-05-13
Huffman編碼m檔案分析

偶苦思一小時餘,方得正果,願與大家分享之。
E-MAIL:mmm@bbi.edu.cn
function [h,l]=huffman(p)
if (length(find(p<0))~=0)
   error('Not a prob,negative component');
end
if (abs(sum(p)-1)>10e-10)
   error('Not a prob.vector,component do not add to 1')
end
n=length(p);
q=p;
m=zeros(n-1,n);
for i=1:n-1
   [q,l]=sort(q);
   m(i,:)=[l(1:n-i+1),zeros(1,i-1)];
   q=[q(1)+q(2),q(3:n),1];
end
for i=1:n-1
   c(i,:)=blanks(n*n);
end
c(n-1,n)='0';
c(n-1,2*n)='1';
for i=2:n-1
   c(n-i,1:n-1)=c(n-i+1,n*(find(m(n-i+1,:)==1))...
                -(n-2):n*(find(m(n-i+1,:)==1)));
   c(n-i,n)='0';
   c(n-i,n+1:2*n-1)=c(n-i,1:n-1);
   c(n-i,2*n)='1';
   for j=1:i-1
      c(n-i,(j+1)*n+1:(j+2)*n)=c(n-i+1,...
         n*(find(m(n-i+1,:)==j+1)-1)+1:n*find(m(n-i+1,:)==j+1));
   end
end 

   for i=1:n
      h(i,1:n)=c(1,n*(find(m(1,:)==i)-1)+1:find(m(1,:)==i)*n);
      ll(i)=length(find(abs(h(i,:))~=32));
   end
   l=sum(p.*ll);
[h,l]=huffman(p),輸入為一維行矩陣p,p為各符號的概率分佈,概率和為1,各元素值為
正,輸出H矩陣為對應每個符號概率的碼字,L為輸出碼字的平均碼長。Huffman .m運用典
型的IF和FOR控制流迴圈語句,該程式包括兩個IF 控制流和5個FOR 迴圈結構。
第一個IF 語句判斷輸入P矩陣各元素是否全為大於零的有效概率值;第二個IF 語句判斷
輸入矩陣的概率和是否為合理值1。
N取輸入行向量P的長度,即需要編碼元素個數。
M為N-1行、N列矩陣,用來記錄每行最小兩概率疊加後概率排列次序。
第一個FOR 迴圈確定概率大小值的排列,得到M矩陣。
第二個FOR迴圈生成一個N-1行、N2(N×N)列矩陣C,每行可看作N個段,每段長為N,記
錄一個碼字(每個碼字的長度不會超過N)。
給C矩陣的N-1行的第一個段賦值0,第二個段賦值1,這兩個碼字對應編碼中最後相加為一
的兩個概率。
第三個迴圈是本程式的主要部分,迴圈N-2次,決定矩陣C從倒數第二行開始到第一行的每
段的碼字值。每一行值都從下一行值得到,找到在下一行碼字中相加本行最小兩個概率得
到的概率的對應碼字,本行兩個最小概率對應碼字分別為此碼字最後加“0”,加“1”。
巢狀的第四個FOR迴圈找到其餘的本行在下一行對應的碼字,該碼字保持不變。迴圈結束
後,C矩陣第一行的N段對應輸入N個概率所對應符號的碼字。該碼字按碼字長短排列。
第五個FOR迴圈根據M矩陣第一行記錄的概率排序位置分配給每個概率對應符號的碼字。
FOR EXAMPLE:
P=[1/6,1/4,5/12,1/6];
N=4;
M矩陣:
     m =[ 1 4 2 3;2 1 3 0;2 1 0 0]



N矩陣:

     n =[1110     1110          110       0;
           10       11            0        ;
            0        1                      ]


注:huffman.m from <<contemporary communication systems using MATLAB>>
    written by John G.Proakis ,Masoud Salehi

相關文章