給定 n 個權值作為 n 個葉子結點,構造一棵二叉樹,若該樹的帶權路徑長度(wpl)達到最小,稱這樣的二叉樹為最優二叉樹,也稱為哈夫曼樹(huffman tree), 還有的書翻譯為霍夫曼樹。
赫夫曼樹是帶權路徑長度最短的樹,權值較大的結點離根較近。
一些概念:
路徑和路徑長度:在一棵樹中,從乙個結點往下可以達到的孩子或孫子結點之間的通路,稱為路徑。通路中分支的數目稱為路徑長度。若規定根結點的層數為 1,則從根結點到第 l層結點的路徑長度為 l-1。
結點的權及帶權路徑長度:若將樹中結點賦給乙個有著某種含義的數值,則這個數值稱為該結點的權。結點的帶權路徑長度為:從根結點到該結點之間的路徑長度與該結點的權的乘積。
樹的帶權路徑長度:樹的帶權路徑長度規定為所有葉子結點的帶權路徑長度之和,記為 wpl(weighted path length) ,權值越大的結點離根結點越近的二叉樹才是最優二叉樹。
wpl 最小的就是赫夫曼樹。
將乙個陣列建立為赫夫曼樹。因為涉及到排序,就借用list實現。
首先建立樹結點。為了實現自定義類的排序,讓樹節點實現comparable介面,重寫compareto方法。這樣做的目的是我們可以呼叫collections.sort()或.sort()方法對我們的自定義類node組成的list進行從小到大排序。(如果需要從大到小排序,compareto方法就寫成-(this.value-o.value))
class
node
implements
comparable
//前序遍歷
public
void
preorder()
if(this
.right!=null)
}@override
public string tostring()
';}@override
public
intcompareto
(node o)
}
接下來進行赫夫曼樹的建立,思路如下:
接收乙個陣列,為了方便排序,以陣列的值依次建立node樹結點並存入list nodes裡。
對nodes進行從小到大排序
取出最小的和第二小的node,也就是nodes下標為0和1的。
用他倆建立一棵樹,他倆是左右子節點,根節點的值為他倆的值之和。
把他倆從nodes裡取出來,因為用過了,把樹的根節點加入nodes並且重新排序。
重複以上過程直到全部合成一棵樹,也就是nodes裡只剩下乙個根節點。
* 建立赫夫曼樹
*/public
class
huffmantree
; node root =
createhuffmantree
(arr)
;preorder
(root);}
//前序遍歷
public
static
void
preorder
(node root)
else
}public
static node createhuffmantree
(int
arr)
//對自定義的類排序,類裡面重寫了compareto方法
collections.
sort
(nodes)
;//建立赫夫曼樹,直到list裡只剩乙個
while
(nodes.
size()
>1)
return nodes.
get(0);}}
赫夫曼樹的建立
赫夫曼樹,即最優二叉樹。給定n個權值作為n個葉子結點,構造一棵二叉樹,若該樹的帶權路徑長度達到最小,稱這樣的二叉樹為最優二叉樹,也稱為哈夫曼樹 huffman tree 哈夫曼樹是帶權路徑長度最短的樹,權值較大的結點離根較近。構造赫夫曼樹 把節點的權值按從小到大的順序排列。從序列中取出前兩個 最小 ...
哈夫曼樹,赫夫曼樹
參考 赫夫曼樹,別名 哈夫曼樹 最優樹 以及 最優二叉樹 當用 n 個結點 這些結點都作為葉子結點且都有各自的權值 試圖構建一棵樹時,如果構建的這棵樹的帶權路徑長度最小,稱這棵樹為 最優二叉樹 有時也叫 赫夫曼樹 或者 哈夫曼樹 構建哈夫曼樹 在 n 個權值中選出兩個最小的權值,對應的兩個結點組成乙...
赫夫曼樹 樹
在資料膨脹,資訊 的今天,資料壓縮的意義不言而喻。談到資料壓縮,就不能 不提赫夫曼編碼,赫夫曼編碼是首個使用的壓縮編碼方案,即使在今天的知名壓縮演算法裡,依然可以見到赫夫曼編碼的影子。另外,在資料通訊中,用二進位製給每個字元進行編碼時不得不面對乙個問題是如何使電文總長最短且不產生二義性。根據字元出現...