路徑:兩個節點之間分支的連線即兩個節點之間的路徑。
路徑長:兩個節點之間路徑所包含分支的和。
深度:根節點的深度為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的值的和則是這個節點的值,根節點是...