哈夫曼樹,又稱最優二叉樹,它是樹的帶權路徑長度值為最小的一棵二叉樹,可用於構造最優編碼,在資訊傳輸、資料壓縮等方面有著廣泛的應用。
1、路徑
樹中乙個結點到另乙個結點之間的分值序列。
2、路徑長度
路徑上分支的條數。
3、結點的權
給結點賦予的數值。
4、帶權路徑長度
結點的權值與該結點
5、樹的帶權路徑長度
樹中所有葉子結點的帶權路徑長度之和,記為wpl(只計算葉子結點)
如下圖的例子,結點數相同,結構不同,計算得到的wpl也就不同。
哈夫曼根據最優二叉樹的特點:
權值越大,離根越近。給出了構造的方法,因此最優二叉樹又稱哈夫曼樹。
6、最優二叉樹
在葉子個數n已經各葉子權值wi確定的條件下,樹的帶權路徑長度wpl值最小的二叉樹稱為最優二叉樹。
(1)初始化
按給定的 n 個權值 ,構造 n 棵二叉樹的集合f = ,其每棵二叉樹只含有乙個權值為 wi 的根結點,左右子樹為空樹;
(2)在f中選取根結點權最小的兩棵二叉樹,分別作為左、右子樹構造一棵新的二叉樹,並置新二叉樹根結點的權值為其左、右子樹根結點的權值之和;
(3)從f中刪除選中的兩棵樹,並插入剛生成的新樹。
(4)重複執行(2)和(3)兩步,直至f 中只含一棵樹為止。
例1:已知權值 w=,構造哈夫曼樹。
(1)初始化:構造n棵二叉樹的集合f=;
(2)在f中選取根結點權值最小的兩棵樹作為子樹構造一棵新的二叉樹;
此時選取最小的4和3,構造一棵新樹,根權值為7。
(3)從f中刪除這兩棵樹,同時加入剛生成的新樹。
重複執行(2)和(3)步,直至只剩下一棵樹,結束。
對於給定的n個葉子結點,構造哈夫曼樹,其最終總的結點數一定是:2n-1。
可選用靜態鍊錶作為儲存結構。即用含2n-1個元素的陣列來儲存哈夫曼樹,結點間的父子關係用下標來指示。
在使用哈夫曼樹進行編碼和解碼時,既要用結點的雙親資訊,又要用結點的孩子資訊,所以採用靜態三叉鍊錶儲存哈夫曼樹。
看下面例子的哈夫曼樹可用**中的靜態三叉鍊錶來表示。
下面給出靜態鍊錶的定義:
#define n 20
#define m 2*n-1
typedef
struct
htnode,huffmantree[m+1]
;
初始化
葉子賦權值、父子游標均置0(下標1~n 對應的結點),其餘結點各域全賦值0(下標n+1~2n-1對應的結點)
迴圈(i=n+1~2n-1)執行(1)(2),構建哈夫曼樹
(1)選擇最小樹:
選擇根結點(父域為0的結點)權值最小的兩棵二叉樹,選擇範圍是下標為1~i-1的結點
(2)構造新樹:
計算新結點i的權值,重新結點左、右孩子域,2棵子樹雙親域賦值(隱含實現了從f中刪除這兩棵樹)
例子:靜態鍊錶的陣列是這樣的:
先給葉子結點賦初值,然後給待完成的分支節點賦全零,
然後選小樹,例如,選擇權值為3和2的3號和4號結點,構造權值為5的6號結點,填入**,同時將3號和4號結點的根結點改為6,以此類推……構造新樹n-1次。
;//給n個葉子結點賦初值
m=2*n-1
;for
(i=n+
1;i<=m;i++
) ht[i]=;
//給n-1個待構建的新樹根結點賦初值
for(i=n+
1;i)}
哈夫曼編碼 哈夫曼樹
1.定義 哈夫曼編碼主要用於資料壓縮。哈夫曼編碼是一種可變長編碼。該編碼將出現頻率高的字元,使用短編碼 將出現頻率低的字元,使用長編碼。變長編碼的主要問題是,必須實現非字首編碼,即在乙個字符集中,任何乙個字元的編碼都不是另乙個字元編碼的字首。如 0 10就是非字首編碼,而0 01不是非字首編碼。2....
哈夫曼樹 哈夫曼編碼
定義從a結點到b結點所經過的分支序列為從a結點到b結點的路徑 定義從a結點到b結點所進過的分支個數為從a結點到b結點的路徑長度 從二叉樹的根結點到二叉樹中所有結點的路徑長度紙盒為該二叉樹的路徑長度 huffman樹 帶權值路徑長度最小的擴充二叉樹應是權值大的外界點舉例根結點最近的擴充二叉樹,該樹即為...
哈夫曼編碼 哈夫曼樹
哈夫曼樹是乙個利用權值進行優化編碼的乙個比較奇怪的樹,他的實現比較簡單,用途也比較單一。哈夫曼樹的實現,實現要求 通過哈夫曼樹可以保證在編碼過程中不會出現例如 1000和100這樣的編碼規則,否則就會編碼失敗,因為1000和100在某些情況下的編碼會一模一樣。通過哈夫曼樹可以保證權值大的值進行編碼時...