Huffman演算法

iteye_401發表於2011-07-04

Huffman演算法是一種用來構造最優字首碼(Huffman編碼)的貪心演算法。Huffman編碼是一種被廣泛應用而且有效的資料壓縮技術,它主要針對字元檔案的壓縮。

Huffman演算法可能產生具有不同編碼的最優字首碼,這句話需要這麼理解:最優字首碼之所以稱為最優是因為它的代價是最小的,但是具有最小代價的編碼可能不止一種,而Huffman演算法恰恰可以產生多種形式的最優字首碼(代價是相同的)。

Huffman(C)
/* C是待編碼的字符集合,|C|=n,對於任意c∈C,c在檔案中的出現頻度為f(c)。Q是一個最小優先順序佇列。Q在具體實現時可以考慮採用最小二叉堆。
該演算法自底向上地構造一棵最優字首碼所對應的樹T*/

n ← |C|
Q ← C
for i ← 1 to n-1
     do 
            allocate a new node z
            left[z] ← x ← Extract-Min(Q)
            right[z] ← y ← Extract-Min(Q)
            f[z] ← f[x] + f[y]
            Insert(Q, z)
return Extract-Min(Q)  // return the root of the tree
            

上面過程所產生的樹稱為Huffman樹,它是一棵滿樹(樹中的每個非葉結點都有兩個子結點),滿樹也是最優編碼的充分條件。非葉結點的左枝上編碼0,右枝編碼1,每個葉子結點的編碼是從根結點到該葉子結點的枝上的0、1串構成。

新節點z以x和y分別作為其左右子結點,由於左右的次序是任意的,因而Huffman演算法得到的最優字首碼不唯一。Huffman演算法的時間複雜度為O(n)。


Huffman演算法為什麼屬於貪心演算法?

Huffman樹的構建過程實際上是對最小頻度的字元的貪心選擇上進行的,具有|C|個字元的字符集需要執行|C-1|次合併得到Huffman樹,每次合併的時候選擇最小頻度的兩個葉結點(包括合併後新產生的結點),而若用頻度表示代價,則在每一步所有可能的合併中,Huffman總是選擇一個代價最小的合併,此即為貪心。




相關文章