哈夫曼編碼的MATLAB實現


本代碼靈感來自於百度上某篇使用sort()函數實現哈夫曼編碼的文章,原文過於復雜。
於是本人按照邏輯重寫過程得到下述代碼,可謂思路清晰,方法簡潔。由於試驗的量也不是很大,所以性能或許不好?嗯……管他的呢
唯一難讀的地方在於MAP函數的補全部分,但其實和哈夫曼編碼最后自頂向下得到編碼的過程邏輯一致。

sort()函數是MATLAB中比較方便的一個排序函數。

[A,B]=sort(C),其中C為亂序概率序列,可得:

  1.A為C的升序序列
  2.B為A對應數字在C中的原始位置

(1)由 A 我們可以得到C序列中 最小值 和 次小值 ,用於哈夫曼編碼中最小值和次小值相加。
(2)由 B 可以知道兩個值在原始序列中的位置,用於記錄本次加法對應的“ 0 ”和“ 1 ”。

那么我們可以把它記錄下來作為哈夫曼編碼中加法合並的路徑,記作MAP矩陣。

合並后的序列在原序列的基礎上生成,兩項的和統一賦值給較大值,較小值則賦一個用不到的極大值即可,此處用5。

    [0.2 0.19 0.17 0.18 0.15 0.01 0.1]
 --->[0.2 0.19 0.17 0.18 0.15   5   0.11]

反復操作后,即依次合並最小兩項,得到合成的全路線如下:

補全所有的值后得到完整的MAP,倒着輸出就可以

下面貼上完整的代碼。

clc;clear;
p=[0.2 0.19 0.17 0.18 0.15 0.01 0.1];
n=length(p);
List=p;
Op_List=p;
Map=[];%Map用於進行huffman 編碼,下面生成(n-1)*(n*n)的矩陣
for i=1:n-1
    Map=[Map;blanks(n)]; 
end

for i=1:n-1
    [Op_List,e]=sort(Op_List);% e 記錄了原來的順序
    
    %e(1)e(2)就是合並的兩個數,小的賦1大的賦0
    Map(i,e(1))='1';
    Map(i,e(2))='0';
    %第一第二加到第二個,第一個作廢
    Op_List(2)=Op_List(1)+Op_List(2);
    Op_List(1)=n;
    
    %位置還原
    Back_List=zeros(1,n);
    for j=1:n
        Back_List(e(j))=Op_List(j);
    end
    Op_List= Back_List; 
end

x=n;y=n-1;%補全Map
for i=y:-1:1
    for j=1:x
        if Map(i,j)~=' '
            for k=i-1:-1:1
                if Map(k,j)~=' '
                    for b=1:x
                        if b~=j && Map(k,b)~=' '
                            Map(k+1:y,b)=Map(k+1:y,j);
                        end
                    end
                end
            end
        end
    end
end
Map

%輸出
for j=1:n
    fprintf('    概率:%.2f',p(j));
    fprintf('    哈夫曼編碼:   ');
    for i=y:-1:1
       if Map(i,j)~=' '
           fprintf('%c',Map(i,j));
       end
    end
    fprintf('\n');
end


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM