1. 程式人生 > >【資料結構與演算法】 利用哈夫曼樹進行檔案壓縮 (部分借鑑網上內容)

【資料結構與演算法】 利用哈夫曼樹進行檔案壓縮 (部分借鑑網上內容)

哈夫曼編碼(Huffman Coding),又稱霍夫曼編碼,是一種編碼方式,哈夫曼編碼是可變字長編碼(VLC)的一種。Huffman於1952年提出一種編碼方法,該方法完全依據字元出現概率來構造異字頭的平均長度最短的碼字,有時稱之為最佳編碼,一般就叫做Huffman編碼(有時也稱為霍夫曼編碼)。

演算法:1、給定一個具有n個權值{ w1,w2,………wn }的結點的集合 F = { T1,T2,………Tn } 2、 初始時,設集合 A = F。 3、 執行 i = 1 至 n -1 的迴圈,在每次迴圈時執行以下操作 從當前集合中選取權值最小、次最小的兩個結點,以這兩個結點作為內部結點 bi 的左右兒子,bi 的權值為其左右兒子權值之和。 在集合中去除這兩個權值最小、次最小的結點,並將內部結點bI 加入其中。這樣,在集合A中,結點個數便減少了一個。 這樣,在經過了n-1 次迴圈之後,集合A中只剩下了一個結點,這個結點就是根結點。

哈夫曼樹的儲存:在哈夫曼樹中,每個要編碼的元素是一個葉結點(度數為零),其它結點都是度數(度數就是有多少個子節點)為2的節點 一旦給定了要編碼的元素個數,由n0=n2+1可知哈夫曼樹的大小為2n-1 哈夫曼樹可以用一個大小為2n的陣列來儲存。0節點不用,根存放在節點1。葉結點依次放在n+1到2n的位置 每個陣列元素儲存的資訊:結點的資料、權值和父結點和左右孩子的位置。

 求葉結點的編碼:

  該過程實質上就是在已建立的哈夫曼樹中,從葉結點開始,沿結點的雙親鏈域回退到根結點,每回退一步,就走過了哈夫曼樹的一個分支,從而得到一位哈夫曼碼值。由於一個字元的哈夫曼編碼是從根結點到相應葉結點所經過的路徑上各分支所組成的 0、1 序列,因此先得到的分支程式碼為所求編碼的低位,後得到的分支程式碼為所求編碼的高位碼。我們可以設定一個結構陣列 HuffCode 用來存放各字元的哈夫曼編碼資訊,陣列元素的結構中有兩個域:bit 和 start。其中,域 bit 為一維陣列,用來儲存字元的哈夫曼編碼, start 表示該編碼在陣列 bit 中的開始位置。所以,對於第 i 個字元,它的哈夫曼編碼存放在 HuffCode[i].bit 中的從 HuffCode[i].start 到 n 的 bit 位中。