在数据结构与算法中,人们把最小带权路径长度的二叉树称为霍夫曼树或者最优二叉树。
通俗的说就是各叶子节点的值和节点的路径长度相乘的值的和。最小的那种类型的二叉树就是霍夫曼树。
霍夫曼树的构造思想是,先将权值集合看作只有一个节点的树的集合,每次选最小的两个权值的树构造一颗新树,新树根节点的权值是左右子树的权值和,在权值集合中删除这两颗权值最小的树,将新生成的树放入权值集合中。如此重复下去,直到权值集合中只有一个元素,这就是最后整棵树的根节点了。
左子树路径看做0,右子树路径看做1的话,一个叶子节点的路径就可以通过01表示。这就是霍夫曼编码,每个节点的霍夫曼编码是不会相同的。
package com.tree; import java.util.*; /** * yuyong 2012-11-2 */ public class HuffmanTree { Node treeRoot=null; HuffCode huff=new HuffCode(); public HuffmanTree(SortedListvalues){ while(true){ Node first=values.get(0); values.remove(0); Node root=first; if(values.size()<=0){ treeRoot=root; break; } Node two=values.get(0); if(two!=null){ values.remove(0); root=new Node(null,first.weight+two.weight); root.left=first; root.right=two; values.insertItem(root); } } } public static void main(String args[]) throws Exception{ long start=new Date().getTime(); SortedList list=new SortedList (SortedList.ASC); for(int i=0;i<5;i++){ int value=(int)(Math.random()*100); list.insertItem(new Node(value, value)); } long end=new Date().getTime(); System.out.println("共耗时:"+(end-start)); System.out.println(list); HuffmanTree ht=new HuffmanTree(list); System.out.println("霍夫曼编码"); ht.show(ht.treeRoot,0); } void show(Node node,int c){ if(node.left!=null){ huff.put(c,0); show(node.left, c + 1); } if(node.value!=null) System.out.println("权重:"+node.weight+" 霍夫曼编码值:"+huff.toString().substring(0,c)); if(node.right!=null){ huff.put(c,1); show(node.right, c + 1); } } } class Node{ Object value; int weight; Node left; Node right; public Node(Object value,int weight){ this.value=value; this.weight=weight; } public boolean equals(Object obj){ Node node=(Node) obj; if(node.weight==this.weight&&node.value==this.value) return true; return false; } } class SortedList extends LinkedList { public static String DESC="desc"; public static String ASC="asc"; public String sort; public SortedList(String sort) throws Exception{ if(sort.equals(DESC)) this.sort=DESC; else if(sort.equals(ASC)) this.sort=ASC; else throw new Exception("no support sort"); } public void insertItem(T value){ int index=0; if(this.size()>0){ int start=0; int end=this.size()-1; int step=0; if(start!=end) while((end-start)!=1){ step=(end-start)/2; if(this.get(start+step).weight>value.weight){ end=end-step; }else if(this.get(start+step).weight =this.get(end).weight){ index=end+1; }else if(value.weight<=this.get(start).weight){ index=start; }else index=end; } this.add(index,value); } public String toString(){ String str="["; for(int j=0;j
共耗时:0
[25,40,45,55,67]
霍夫曼编码
权重:45 霍夫曼编码值:00
权重:55 霍夫曼编码值:01
权重:25 霍夫曼编码值:100
权重:40 霍夫曼编码值:101
权重:67 霍夫曼编码值:11