概念
哈夫曼编码应用广泛,如JPEG中就应用了哈夫曼编码。
哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。树的带权路径长度记为WPL= (W1*L1+W2*L2+W3*L3+…+Wn*Ln),N个权值Wi(i=1,2,…n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,…n)。可以证明哈夫曼树的WPL是最小的。
哈夫曼编码步骤:
一、对给定的n个权值{W1,W2,W3,…,Wi,…,Wn}构成n棵二叉树的初始集合F= {T1,T2,T3,…,Ti,…,Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空。(为方便在计算机上实现算 法,一般还要求以Ti的权值Wi的升序排列。)
二、在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树,新二叉树的根结点的权值为其左右子树的根结点的权值之和。
三、从F中删除这两棵树,并把这棵新的二叉树同样以升序排列加入到集合F中。
四、重复二和三两步,直到集合F中只有一棵二叉树为止。
java实现
package com.cn;
import java.util.ArrayList;
import java.util.List;
//定义树的节点
class TreeNode{
int weight; //权重
TreeNode leftNode;//左子树
TreeNode rightNode;//右子树
TreeNode parentNode;//根节点
//构造函数
public TreeNode(){}
public TreeNode(int weight){
this.weight = weight;
}
@Override
public String toString(){
return this.weight + "";
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
public class HuffmanTree {
public static void main(String[] args) {
int[] a = new int[]{2,21,12,24,12};
List list = new ArrayList();
HuffmanTree ht = new HuffmanTree();
ht.SortWeight(a, list);
TreeNode root = ht.CreatTree(list);
ht.print(root);
}
//首先将数组中的每个数,生成一课单独的树,然后将所有的这些树添加进list集合中,并对其进行排序
public void SortWeight(int[] a,List list){
for(int i = 0; i < a.length; i++){
TreeNode node = new TreeNode(a[i]);
list.add(node);
}
//排序
list.sort((o1,o2)->((TreeNode)o1).getWeight() - ((TreeNode)o2).getWeight());
System.out.println(list);
}
//构建哈夫曼树
public TreeNode CreatTree(List list){
if(list.size() <= 1){
return null;
}
//集合中的元素个数必须大于1才可以
// while(list.size() > 1){
//获取集合中权值最小的两个节点,并将其从集合中删除
TreeNode node1 = (TreeNode)list.remove(0);
TreeNode node2 = (TreeNode)list.remove(0);
//根据两个小节点,创建他们的父节点
TreeNode node3 = new TreeNode();
node3.weight = node1.weight + node2.weight;
//建立三个节点之间的关系
node3.leftNode = node1;
node3.rightNode = node2;
node1.parentNode = node3;
node2.parentNode = node3;
//把父节点添加进集合,并重新排序
list.add(node3);
list.sort((o1,o2)->((TreeNode)o1).getWeight() - ((TreeNode)o2).getWeight());
// }
CreatTree(list);
TreeNode root = (TreeNode)list.get(0);
return root;
}
//前序遍历哈夫曼树
public void print(TreeNode root){
if(root == null){
return;
}
System.out.print(root.weight + " ");
print(root.leftNode);
print(root.rightNode);
}
}
/**
输出结果:
[2, 12, 12, 21, 24]
71 26 12 14 2 12 45 21 24
*/
资料收集自:
哈夫曼树http://blog.youkuaiyun.com/shuangde800/article/details/7341289
java实现哈夫曼树http://2509477698.iteye.com/blog/1683658