哈夫曼树java代码

98 阅读1分钟

在计算机数据处理中,哈夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。 如下为哈夫曼树的java代码


public class HuffmanTree {
    private static class Node{
        public int weight;

        public Node left;

        public Node right;

        public Character data;

        public Node(int weight, Character data) {
            this.weight = weight;
            this.data = data;
        }

        public Node(int weight, Node left, Node right, Character data) {
            this.weight = weight;
            this.left = left;
            this.right = right;
            this.data = data;
        }
    }

    public Map<Character, Integer> getCharMap(String str){
        if (str==null||str.length()==0){
            return new HashMap<>();
        }

        Map<Character, Integer> res = new HashMap<>();
        for (int i = 0; i < str.length(); i++) {
            res.put(str.charAt(i), res.getOrDefault(str.charAt(i), 0)+1);
        }

        return res;
    }

    private Node createTree(PriorityQueue<Node> priorityQueue) {
        if (priorityQueue==null||priorityQueue.isEmpty()){
            return null;
        }

        while (priorityQueue.size()>1){
            Node left = priorityQueue.poll();
            Node right = priorityQueue.poll();
            Node node = new Node(left.weight+right.weight, left, right, null);
            priorityQueue.add(node);
        }

        return priorityQueue.poll();
    }

    Map<Character, String> mapRes = new HashMap<>();
    StringBuilder stringBuilder = new StringBuilder();
    private Map<Character, String> encode(Node root){
        dfs(root.left, '0');
        dfs(root.right, '1');
        return mapRes;
    }

    public void dfs(Node root, Character character){
        if (root==null){
            return;
        }

        stringBuilder.append(character);

        if (root.left==null&&root.right==null){
            mapRes.put(root.data, new String(stringBuilder));
        }
        dfs(root.left, '0');
        dfs(root.right, '1');
        stringBuilder.deleteCharAt(stringBuilder.length()-1);
    }

    public static void main(String[] args) {
        HuffmanTree huffmanTree = new HuffmanTree();
        Map<Character, Integer> charMap = huffmanTree.getCharMap("hkhjkgjhgjdgfjsdgfdsjfgevnbvndsakhkhlfkdsghdfsdvvsdfdsfjdsdwewqeiuoewrbmB");

        PriorityQueue<Node> priorityQueue = new PriorityQueue<>(Comparator.comparingInt(o -> o.weight));
        for (Map.Entry<Character, Integer> mapItem : charMap.entrySet()) {
            priorityQueue.add(new Node(mapItem.getValue(), mapItem.getKey()));
        }
        Node root = huffmanTree.createTree(priorityQueue);
        Map<Character, String> encode = huffmanTree.encode(root);

        System.out.println("-------encode: "+encode);
    }


}