資料結構之哈弗曼樹與哈弗曼編碼

2021-08-16 17:45:50 字數 1823 閱讀 1330

一.哈弗曼樹和哈弗曼編碼先知

哈弗曼樹是二叉樹中一種特殊的樹,也被稱為最優二叉樹。其通過某種規則(權值)來構造出一哈夫曼二叉樹,在這個二叉樹中,只有葉子節點才是有效的資料節點,其他的非葉子節點是為了構造出哈夫曼而引入的!

哈夫曼編碼是通過哈夫曼樹進行的一種編碼,一般情況下,以字元『0』與『1』表示。編碼的實現過程很簡單,只要實現哈夫曼樹,通過遍歷哈夫曼樹,規定向左子樹遍歷乙個節點編碼為「0」,向右子樹遍歷乙個節點編碼為「1」,結束條件就是遍歷到葉子節點!因為上面說過:哈夫曼樹葉子節點才是有效資料節點!

二.構造哈弗曼樹

假設有n個權值,則構造出的哈夫曼樹有n個葉子結點。 n個權值分別設為 w1、w2、…、wn,則哈夫曼樹的構造規則為:

(1) 將w1、w2、…,wn看成是有n 棵樹的森林(每棵樹僅有乙個結點);

(2) 在森林中選出兩個根結點的權值最小的樹合併,作為一棵新樹的左、右子樹,且新樹的根結點權值為其左、右子樹根結點權值之和;

(3)從森林中刪除選取的兩棵樹,並將新樹加入森林;

(4)重複(2)、(3)步,直到森林中只剩一棵樹為止,該樹即為所求得的哈夫曼樹。

例子:

我們用圖畫來構造一顆哈弗曼樹

注意:為了使得到的哈夫曼樹的結構盡量唯一,通常規定生成的哈夫曼樹中每個結點的左子樹根結點的權小於等於右子樹根結點的權。

三.哈弗曼編碼

哈夫曼編碼使用一種特別的方法為訊號源中的每個符號設定二進位製碼。出現頻率更大的符號將獲得更短的位元,出現頻率更小的符號將被分配更長的位元,以此來提高資料壓縮率,提高傳輸效率。具體編碼步驟主要為,

1、統計:

在開始編碼時,通常都需要對訊號源,也就是本文的一段文字,進行處理,計算出每個符號出現的頻率,得到訊號源的基本情況。接下來就是對統計資訊進行處理了

2、構造優先對列:

把得到的符號新增到優先佇列中,此優先佇列的進出邏輯是頻率低的先出,因此在設計優先佇列時需要如此設計,如果不熟悉優先佇列,請閱讀相關書籍,在此不做過多概述。得到包含所有字元的優先佇列後,就是處理優先佇列中的資料了。

3、構造哈夫曼樹:

哈夫曼樹是帶權值得二叉樹,我們使用的哈夫曼樹的權值自然就是符號的頻率了,我們構建哈夫曼樹是自底向上的,先構建葉子節點,然後逐步向上,最終完成整顆樹。先把佇列中的乙個符號出列,也就是最小頻率的符號,,然後再出列乙個符號。這兩個符號將作為哈夫曼樹的節點,而且這兩個節點將作為新節點,也就是它們父節點,的左右孩子節點。新節點的頻率,即權值,為孩子節點的和。把這個新節點新增到佇列中(佇列會重新根據權值排序)。重複上面的步驟,兩個符號出列,構造新的父節點,入列……直到佇列最後只剩下乙個節點,這個節點也就是哈夫曼樹的根節點了。

4、為哈弗曼樹編碼:

哈夫曼樹的來自訊號源的符號都是葉子節點,需要知道下。樹的根節點分配位元0,左子樹分配0,右字數分配1。然後就可以得到符號的碼值了。

例如上邊的例子:

這樣各個字元對應的編碼分別為:

a——011

b——00001

c——1

d——00000

e——001

f——010

g——0001

四.參考文獻

哈弗曼編碼 哈弗曼樹

哈弗曼編碼是依賴於字元使用頻率來建立的一種編碼,通過把使用頻率低的字元分配相對較多的01編碼,而使用頻率高的分配相對較低的01編碼,來建立最小的帶權路徑長度的樹,來最大化的獲得編碼儲存空間的一種編碼規則。這個樹稱為哈弗曼樹,也稱為最優二叉樹。這樣可以確定每乙個字元的編碼不可能成為其他字元編碼的坐子串...

哈弗曼樹與哈弗曼編碼(實現)

歷史背景 1951年,霍夫曼在mit攻讀博士學位,他和修讀資訊理論課程的同學得選擇是完成學期報告還是期末考試。導師robert fano出的學期報告題目是 查詢最有效的二進位制編碼。由於無法證明哪個已有編碼是最有效的,霍夫曼放棄對已有編碼的研究,轉向新的探索,最終發現了基於有序頻率二叉樹編碼的想法,...

哈弗曼編碼

include include include define my strmax 100 define infinity 1000000 typedef struct htnode,huffmantree 動態分配陣列儲存赫夫曼樹 typedef char huffmancode 動態分配陣列儲存赫...