哈夫曼樹的搭建與哈夫曼編碼

2021-09-05 04:00:57 字數 3735 閱讀 7705

路徑:兩個節點之間分支的連線即兩個節點之間的路徑。

路徑長:兩個節點之間路徑所包含分支的和。

深度:根節點的深度為0,其子節點的深度為1,往下逐一遞推。

子節點數:和普通的樹不同,二叉樹從根節點出發,每個節點最多只能有兩個子節點。

滿二叉樹:除了葉子結點,每個節點都有兩個子節點。

哈夫曼樹是一種最優的二叉樹,它的帶權路徑最短。那麼怎麼算乙個二叉樹的權值呢?我們從根節點開始遞推,根節點的權值為0,隨著深度的遞增,權值也遞增,同一深度的節點權值是相同的,每個節點都有它的資料值,每個節點的資料值乘權值累加即可得到樹的權值,哈夫曼樹是帶權路徑最短的樹。如圖:

權值1=73+53+32+11=43

權值2=13+33+52+71=29

比較這兩棵樹的權值我們可以發現:要使帶權路徑最短,較大的數應該靠上放,較小的靠下放。第二張圖才是帶權路徑最短的二叉樹,即最優二叉樹(哈夫曼樹)。

把需要用來構建哈夫曼樹的陣列進行排序。

取最小的兩個數作為葉子結點,生成雙親節點,雙親節點的值為二者的值之和。

從陣列中刪除這兩個節點,新增生成的雙親節點入陣列並重新排序。

重複以上操作直至陣列只剩下乙個新生成的節點,它就是哈夫曼樹的根節點。

1、節點類:

這是一種支援泛型的節點類,我們定義了一些方法來操作節點的資料。

public

class

node

implements

comparable

>

/** * 獲取節點資料

*/public string tostring()

/** * 節點權值比較方法

* @param o

* @return

*/public

intcompareto

(node

o)public

void

setdata

(t data)

public

void

setweight

(int weight)

public t getdata()

public

intgetweight()

public

void

setleft

(node

node)

public

void

setright

(node

node)

public node

getleft()

public node

getright()

}

2、建樹:

步驟:1、輸入字串。

2、統計各字元出現的次數,生成ascii碼陣列。

3、用陣列生成節點並存放在鍊錶中。

4、根據字元出現頻率對鍊錶中的節點進行排序。

5、根據鍊錶中的有序節點生成哈夫曼樹。

6、根據哈夫曼樹獲取輸入字元對應的哈夫曼編碼值,存入hashmap。

public

class

create

node

root = ct.

createhfmtree

(list)

;//建樹

system.out.

println

("根節點權重:"

+root.

getweight()

);

system.out.

println

("列印整棵樹、、、、");

ct.inorder

(root)

;//列印整棵樹

system.out.

println

("獲取葉子結點哈夫曼編碼");

hashmap

map = ct.

getallcode

(root);}

/** * 通過字串獲取陣列的方法

* @param str

*/public

int[

]getarrays

(string str)

return arrays;

}/**

* 把獲得的陣列轉化為節點並存在鍊錶中

* @param arrays

* @return

*/public linkedlist

>

createnodelist

(int

arrays)

}return list;

}/**

* 對鍊錶中的元素排序

* @param list

* @return

*/public

void

sortlist

(linkedlist

> list)}}

}/**

* 建樹的方法

* @param list

*/public node

createhfmtree

(linkedlist

> list)

return list.

get(0)

;//返回根節點

}public hashmap

getallcode

(node

root)

/** * 查詢指定字元的哈弗曼編碼(中序遍歷)

* @param code

* @param st

* @param root

* @return

*/public

void

inordergetcode

(string code ,hashmap

map,node

root)

inordergetcode

(code+

"1",map,root.

getright()

);}}

/** * 中序遍歷輸出整棵樹

* @param root

* @return

*/public

void

inorder

(node

root)

}}

3、測試:

輸入一字串,選取幾個key值觀察其對應的編碼值是否和理論值相同:

1、輸入字串,獲得了一些節點資料。

2、排序整理。

3、建樹並返回根節點,列印權值。

4、列印整棵樹,觀察中序遍歷是否正確。

5、在往hashmap存值前列印字元和編碼的對應關係。

哈夫曼樹與哈夫曼編碼

在一般的資料結構的書中,樹的那章後面,著者一般都會介紹一下哈夫曼 huffman 樹和哈夫曼編碼。哈夫曼編碼是哈夫曼樹的乙個應用。哈夫曼編碼應用廣泛,如 jpeg中就應用了哈夫曼編碼。首先介紹什麼是哈夫曼樹。哈夫曼樹又稱最優二叉樹,是一種帶權路徑長度最短的二叉樹。所謂樹的帶權路徑長度,就是樹中所有的...

哈夫曼樹與哈夫曼編碼

1.哈夫曼 huffman 編碼是哈夫曼樹的乙個應用。2.哈夫曼樹又稱為最優二叉樹,是一種帶權路徑長度最短的二叉樹。所謂樹的帶權路徑長度,就是樹中所有的葉結點的相對值乘上其到根結點的路徑和權值。3.影象jpg就是利用了哈夫曼編碼。4.哈夫曼樹是最優二叉樹,子樹有左右次序之分。5.哈夫曼樹的形態不是唯...

哈夫曼樹與哈夫曼編碼

哈夫曼樹是一種簡單的樹結構,建樹過程如下 給出一組資料,不斷選擇最小的兩個數,並用兩個數的和作為它們的parent節點,再從資料中刪除這兩個數,將兩個數的和加入資料中,直到所有的資料都被加入樹結構,形成一顆樹。這顆樹的所有非葉子節點都有兩個child,兩個child的值的和則是這個節點的值,根節點是...