1. 概念
赫夫曼樹: 給定n個權值作爲n個葉子節點,構造一棵二叉樹,若該樹的帶權路徑長度(wpl)達到最小,稱這樣的二叉樹爲最優二叉樹,也叫赫夫曼樹(Huffman Tree)。
路徑:從一個節點往下可以達到的孩子或者孫子節點之間的通路,稱之爲路徑。
路徑長度:通路中的分支數目稱之爲路徑長度,若規定根節點的層數爲1,則從根節點到第L層節點的路徑長度爲L-1。
權:將書中的節點賦給一個有某種意義的數值,則這個數值稱之爲給節點的權。
帶權路徑長度:從根節點到該節點之間的路徑長度與該節點的權的乘積。
2. 將數列轉成赫夫曼樹
- 思路
1、寫Node類,其中Node類需要繼承Comparable類,實現其中的compareTo()方法,爲的是實現Node數組的排序(java自帶的排序)
2、將舉例子的數組值轉化爲list<Node>值並排序 3、將list中最小的兩個node拿出,並構成一個二叉樹,將父節點的值寫成左右子節點的值的和,並將父節點加入到list中去 4、重複2、3操作,直到list只有一個元素。
- 代碼
package tree;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
public class HuffmanTree {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = {2,7,4,3,1,9,8,0};
HuffmanTree huffmanTree = new HuffmanTree();
Node node = huffmanTree.buildHuffmanTree(arr);
System.out.println(node.toString());
}
//構建哈弗曼樹
public Node buildHuffmanTree(int[] arr) {
Node pareNode;
ArrayList<Node> list = new ArrayList<Node>();
//1、將arr轉換爲list,並排序
for (int i = 0; i < arr.length; i++) {
list.add(new Node(arr[i]));
}
// Collections.sort(list);
// System.out.println(list);
while(list.size() > 1) {
Collections.sort(list);
System.out.println(list);
//2、取出最小的兩個數,進行拼接node
pareNode = new Node(list.get(0).getValue()+list.get(1).getValue());
pareNode.setLeftNode(list.get(0));
pareNode.setRightNode(list.get(1));
//3、list剔除lsftNode和rightNode,並加入parentNode
list.remove(0);
list.remove(0);
list.add(pareNode);
}
return list.get(0);
}
}
//樹節點
class Node implements Comparable<Node>{
private int value;
private Node leftNode;
private Node rightNode;
public int getValue() {
return value;
}
public Node(int value) {
this.value = value;
}
public void setValue(int value) {
this.value = value;
}
public Node getLeftNode() {
return leftNode;
}
public void setLeftNode(Node leftNode) {
this.leftNode = leftNode;
}
public Node getRightNode() {
return rightNode;
}
public void setRightNode(Node rightNode) {
this.rightNode = rightNode;
}
@Override
public String toString() {
return "Node [value=" + value + "]";
}
@Override
public int compareTo(Node o) {
// TODO Auto-generated method stub
return this.value - o.getValue();//升序
}
}