哈夫曼树和哈夫曼编码的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,"");
    }
}

posted @ 2021-12-27 16:05  度一川  阅读(71)  评论(0)    收藏  举报