哈夫曼編碼

2021-08-11 05:08:02 字數 1613 閱讀 2625

一、定義

最簡單的二進位制編碼方式是等長編碼。例如,假定電文中只使用a、b、c、d、e、f這六種字元,若進行等長編碼,則需要二進位制的3位,可依次編碼為000,001,010,011,100,101。若用這六個字元作為6個葉子結點,生成一棵二叉樹,讓該二叉樹中每個分支結點的左、右分支分別用0和1編碼,從樹根結點到每個葉子結點的路徑上所經分支的0,1編碼序列應等於該葉子結點的二進位制編碼,則對應的編碼二叉樹如圖7-8所示。

在電文中每個字元的出現頻率(即次數)一般是不同的,假定在乙份電文中,這6個 字元的出現頻率依次為4,2,6,8,3,2

則電文被編碼後的長度=編碼長度*頻率;總長度等於所有長度之和。

若才乙個不等長編碼,讓出現頻率高的字元具有較短的編碼,讓出現頻率低的字元具有較長的編碼,這樣有可能縮短傳送電文的總長度。採用不等長編碼要避免解碼的二義性和多義性。假設用0表示字元d,用01表示字元c,則當接收到編碼串.......01...........,並譯到字元0時,是立即譯出對應的字元d,還是接著與下乙個字元1一起譯為對應的字元c,這就產生了二義性。因此,若對某一字符集進行不等長編碼,則要求字符集中任一字元的編碼都不能是其他字元編碼的字首。符合此要求的編碼叫做無字首編碼。顯然等長編碼是無字首編碼,這從等長編碼所對應的編碼二叉樹也可直觀地看出,任一葉子結點都不可能是其他葉子結點的雙親,也就是說,只有當乙個結點是另乙個結點的雙親時,該結點的字元編碼才會是另乙個結點的字元編碼的字首。

為了使不等長編碼成為無字首編碼,可用該字符集中的每個字元作為葉子結點生成一棵編碼二叉樹,為了獲得傳送電文的最短長度,可將每個字元的出現頻率作為字元結點的權值賦予該結點上,求出此樹的最小帶權路徑長度就等於求出了傳送電文的最短長度。因此,求傳送電文的最短長度問題就轉化為求由字符集中的所有字元作為葉子結點,由字元的出現頻率作為其權值所產生的哈夫曼樹的問題。

根據上面所討論的例子,生成的編碼哈夫曼樹如圖所示,有編碼哈夫曼樹得到的字元編碼稱做哈夫曼編碼。在圖中,a、b、c、d、e、f這六個字元的哈夫曼編碼依次為101、000、01、11、100、001。電文的最短傳送長度為:

顯然,這比等長編碼所得到的傳送電文總長度75要小得多。

對已經介紹過的求哈夫曼編碼帶權路徑長度的演算法略加修改,就可以得到求哈夫曼編碼的演算法。具體給出如下:

//構造哈夫曼編碼

public static void outputhuffmancoding(btreenode ft,int len,inta)

{ //根據ft指標所指向的哈夫曼樹輸出每個葉子的編碼,len初值為0

if(ft!=null)

{ //訪問到葉子結點時輸出其儲存在陣列a中的0和1序列編碼

if(ft.left==null&&ft.right==null)

{system.out.print("結點權值"+(integer)ft.element+"的編碼為:");

for(int i=0;i

哈夫曼編碼 哈夫曼樹

1.定義 哈夫曼編碼主要用於資料壓縮。哈夫曼編碼是一種可變長編碼。該編碼將出現頻率高的字元,使用短編碼 將出現頻率低的字元,使用長編碼。變長編碼的主要問題是,必須實現非字首編碼,即在乙個字符集中,任何乙個字元的編碼都不是另乙個字元編碼的字首。如 0 10就是非字首編碼,而0 01不是非字首編碼。2....

哈夫曼樹 哈夫曼編碼

定義從a結點到b結點所經過的分支序列為從a結點到b結點的路徑 定義從a結點到b結點所進過的分支個數為從a結點到b結點的路徑長度 從二叉樹的根結點到二叉樹中所有結點的路徑長度紙盒為該二叉樹的路徑長度 huffman樹 帶權值路徑長度最小的擴充二叉樹應是權值大的外界點舉例根結點最近的擴充二叉樹,該樹即為...

哈夫曼編碼 哈夫曼樹

哈夫曼樹是乙個利用權值進行優化編碼的乙個比較奇怪的樹,他的實現比較簡單,用途也比較單一。哈夫曼樹的實現,實現要求 通過哈夫曼樹可以保證在編碼過程中不會出現例如 1000和100這樣的編碼規則,否則就會編碼失敗,因為1000和100在某些情況下的編碼會一模一樣。通過哈夫曼樹可以保證權值大的值進行編碼時...