I 哈夫曼樹概念:
給定n個權值作爲n個葉子結點,構造一棵二叉樹,若帶權路徑長度達到最小,稱這樣的二叉樹爲最優二叉樹,也稱爲哈夫曼樹(Huffman Tree)。哈夫曼樹是帶權路徑長度最短的樹,權值較大的結點離根較近。(from Baidu百科)。
II 哈夫曼樹的應用
1、哈夫曼編碼
2、常應用於信息檢索
etc.
III 常用術語
IV 下面重點介紹一下haffman Tree的Java實現,代碼附下:
package pers.me.timlong.tree;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
public class HaffmanTree {
/**
* 內部靜態類Node
* @author lenovo
*
* @param <E>
*/
public static class Node<E>{
private E data;
private double weight;
private Node<E> leftChild;
private Node<E> rightChild;
public Node(E data, double weight) {
this.data = data;
this.weight = weight;
}
@Override
public String toString() {
return "Node[data = " + this.data + ", weight = " + this.weight + "]";
}
}
private static <E> void swap(List<Node<E>> nodes, int i, int j) {
Node<E> temp;
temp = nodes.get(i);
nodes.set(i, nodes.get(j));
nodes.set(j, temp);
}
//實現快速排序,對節點進行排序
private static <E> void subSort(List<Node<E>> nodes, int start, int end) {
if(start < end) {
Node<E> base = nodes.get(start);
int i = start;
int j = end + 1;
while(true) {
while(i < end && nodes.get(++ i).weight >= base.weight) ;
while(j > start && nodes.get(-- j).weight <= base.weight) ;
if(i < j)
swap(nodes, i, j);
else
break;
}
swap(nodes, start, j);
subSort(nodes, start, j);
subSort(nodes, start, j - 1);
}
}
public static <E> void quickSort(List<Node<E>> nodes) {
subSort(nodes, 0, nodes.size() - 1);
}
@SuppressWarnings("rawtypes")
public static List<Node> breadthFirst(Node root){
Queue<Node> queue = new ArrayDeque<>();
List<Node> list = new ArrayList<Node>();
if(null != root) {
queue.offer(root);
}
while(! queue.isEmpty()) {
list.add(queue.peek()); //not remove
Node p = queue.poll(); //remove
if(null != p.leftChild) {
queue.offer(p.leftChild);
}
if(null != p.rightChild) {
queue.offer(p.rightChild);
}
}
return list;
}
public static<E> Node<E> createTree(List<Node<E>> nodes){
while(nodes.size() > 1) {
quickSort(nodes);
Node<E> left = nodes.get(nodes.size() - 1);
Node<E> right = nodes.get(nodes.size() - 2);
Node<E> parent = new Node<E>(null, left.weight + right.weight);
parent.leftChild = left;
parent.rightChild = right;
nodes.remove(nodes.size() - 1);
nodes.remove(nodes.size() - 1);
nodes.add(parent);
}
return nodes.get(0);
}
public static void main(String[] args) {
List<Node<String>> nodes = new ArrayList<Node<String>>();
nodes.add(new Node<String>("A", 40.0));
nodes.add(new Node<String>("B", 7.0));
nodes.add(new Node<String>("C", 10.0));
nodes.add(new Node<String>("D", 30.0));
nodes.add(new Node<String>("E", 12.0));
nodes.add(new Node<String>("F", 2.0));
Node<String> root = HaffmanTree.createTree(nodes);
System.out.println(HaffmanTree.breadthFirst(root));
}
}
打印結果:
[Node[data = null, weight = 101.0],
Node[data = null, weight = 44.0],
Node[data = null, weight = 57.0],
Node[data = null, weight = 14.0],
Node[data = D, weight = 30.0],
Node[data = null, weight = 17.0],
Node[data = A, weight = 40.0],
Node[data = F, weight = 2.0],
Node[data = E, weight = 12.0],
Node[data = B, weight = 7.0],
Node[data = C, weight = 10.0]]
在編程中的應用無處不在,掌握數據結構的底層實現,無疑可以更好地幫助我們提高編程能力與開發效率。
望每天進步一點,