哈夫曼树和哈夫曼编码的java实现
哈夫曼
哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。
构建方法
构成初始集合
对给定的n个权值{W1,W2,W3,...,Wi,...,Wn}构成n棵二叉树的初始集合F={T1,T2,T3,...,Ti,...,Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空。(为方便在计算机上实现算法,一般还要求以Ti的权值Wi的升序排列。)
选取左右子树
在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树,新二叉树的根结点的权值为其左右子树的根结点的权值之和。
删除左右子树
从F中删除这两棵树,并把这棵新的二叉树同样以升序排列加入到集合F中。
重复二和三两步
重复二和三两步,直到集合F中只有一棵二叉树为止。
public HuffmanNode buildHuffmanTree(List<HuffmanNode> list){
if(list.size()==0){
return null;
}
list.sort(Comparator.comparing(e->e.weight)); //排序
while (list.size()>1){
// 每次弹出两个
HuffmanNode node1 = list.remove(0);
HuffmanNode node2 = list.remove(0);
HuffmanNode huffmanNode = new HuffmanNode(null,node1.weight+node2.weight);
huffmanNode.left = node1;
huffmanNode.right = node2;
// 将其插入list
int i=0;
for(;i<list.size();i++){
if(list.get(i).weight>=huffmanNode.weight){
break;
}
}
list.add(i,huffmanNode);
}
return list.get(0);
}
哈夫曼编码
当我们知道哈夫曼树,我们其实就已经知道其编码,我们从根节点出发,其左子树是0而其右子树是1
public void printHuffmanCode(HuffmanNode huffmanNode,String pre){
if(huffmanNode==null){
return;
}
printHuffmanCode(huffmanNode.left,pre+"0");
if(huffmanNode.name!=null){
System.out.println("name:"+huffmanNode.name+"code:"+ pre);
}
printHuffmanCode(huffmanNode.right,pre+"1");
}
全部代码
import java.util.*;
class HuffmanNode{
String name;
int weight;
HuffmanNode left;
HuffmanNode right;
public HuffmanNode(String name, int weight) {
this.name = name;
this.weight = weight;
}
}
public class HuffmanTree {
HuffmanNode root;
public HuffmanTree(HashMap<String,Integer> hashMap){
List<HuffmanNode> list = new ArrayList<>();
for(String name:hashMap.keySet()){
list.add(new HuffmanNode(name,hashMap.get(name)));
}
root = buildHuffmanTree(list);
}
public HuffmanNode buildHuffmanTree(List<HuffmanNode> list){
if(list.size()==0){
return null;
}
list.sort(Comparator.comparing(e->e.weight));
while (list.size()>1){
// 每次弹出两个
HuffmanNode node1 = list.remove(0);
HuffmanNode node2 = list.remove(0);
HuffmanNode huffmanNode = new HuffmanNode(null,node1.weight+node2.weight);
huffmanNode.left = node1;
huffmanNode.right = node2;
// 将其插入list
int i=0;
for(;i<list.size();i++){
if(list.get(i).weight>=huffmanNode.weight){
break;
}
}
list.add(i,huffmanNode);
}
return list.get(0);
}
public void midView(HuffmanNode huffmanNode){
if(huffmanNode==null){
return;
}
midView(huffmanNode.left);
System.out.println(huffmanNode.weight+" "+ huffmanNode.name);
midView(huffmanNode.right);
}
public void printHuffmanCode(HuffmanNode huffmanNode,String pre){
if(huffmanNode==null){
return;
}
printHuffmanCode(huffmanNode.left,pre+"0");
if(huffmanNode.name!=null){
System.out.println("name:"+huffmanNode.name+"code:"+ pre);
}
printHuffmanCode(huffmanNode.right,pre+"1");
}
}
class TestHuffmanNode{
public static void main(String[] args) {
HashMap<String,Integer> nodeMap = new HashMap<>();
nodeMap.put("a",45);
nodeMap.put("c",12);
nodeMap.put("b",13);
nodeMap.put("f",5);
nodeMap.put("d",16);
nodeMap.put("e",9);
HuffmanTree huffmanTree = new HuffmanTree(nodeMap);
huffmanTree.midView(huffmanTree.root);
huffmanTree.printHuffmanCode(huffmanTree.root,"");
}
}
浙公网安备 33010602011771号