哈夫曼樹和哈夫曼編碼(文件壓縮)


哈夫曼樹(Huffman Tree)
帶權路徑長度(WPL):設二叉樹有n個葉子結點,每個葉子結點帶有權值Wk,從根節點到每個葉子結點的長度為Lk,則每個葉子結點帶權路徑長度之和就是(wk* Lk)求和
最優二叉樹或哈夫曼樹:WPL最小的二叉樹

哈夫曼樹的構造:每次把權值最小的兩棵二叉樹合並

 1 HuffmanTree Huffman(MinHeap H)
 2 {
 3     //這里最小堆的元素類型為HuffmanTree,排序的原則是結點的權值數據
 4     //假設H->Size個權值已經存在在H->Data[]->weight里
 5     int i, N;
 6     HuffmanTree T;
 7 
 8     BuildMinHeap(H);        //根據結點的權值將H調整為最小堆
 9     N = H->Size;
10     for (i = 1; i < N; i++)        //做H->Size - 1次合並
11     {
12         T = (HuffmanTree)malloc(sizeof(struct HTNode));        //創建一個新的哈夫曼結點
13         T->Left = DeleteMin(H);        //將最小堆中的最小元素,即根節點刪除后返回,作為這個哈夫曼結點的左子結點
14         T->Right = DeleteMin(H);        //再次將最小堆中的根節點刪除后返回,作為這個哈夫曼樹的右子結點
15         //哈夫曼節點的權值等於左右子節點的權值之和
16         T->weight = T->Left->weight + T->Right->weight;
17         Insert(H, T);
18     }
19 
20     return DeleteMin(H);    //最小堆中最后一個元素即使指向哈夫曼樹根節點的指針
21 }

 

哈夫曼樹的特點:
沒有度為1的結點
n個葉子結點的哈夫曼樹共有2n-1個結點
哈夫曼樹的任意非葉結點的左右子樹交換后仍是哈夫曼樹
對同一組權值,存在不同構的兩棵哈夫曼樹,但兩棵樹的WPL相等

哈夫曼編碼(文件壓縮):
給定一段字符串,如何對字符進行編碼,可以使得該字符串的編碼存儲空間最少

前綴碼:(prefix code)任何字符的編碼都不是另一字符編碼的前綴,可避免二義性
二叉樹表示法:每個字符通過從根節點開始用0指示左分支,用1指示右分支而已記錄路徑的方法表示出來
用二叉樹進行編碼:
(1)左右分支:0、 1
(2)字符只在葉結點上
用哈夫曼樹的規則構造這棵二叉樹

哈夫曼編碼對應的解壓過程:

 依次讀入文件的二進制碼,從哈夫曼樹的根節點出發,若當前讀入0,則走向左孩子,否則走向右孩子。

一旦到達某一葉子時便譯出相應的字符。然后重新從根出發繼續下一個字符的譯碼,直至文件結束


免責聲明!

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



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