优先队列实现哈夫曼编码

首先定义一个TreeNode:

static class TreeNode {
        int weight;//权重,出现次数
        Character ch;//如果是初始字符,则ch为字符,如果是合并的,则为null
        TreeNode left;
        TreeNode right;

        public TreeNode(int weight) {
            this.weight = weight;
        }

        public TreeNode(int weight, Character ch) {
            this.weight = weight;
            this.ch = ch;
        }
    }

之后定义一个优先队列,以TreeNode中weight比较,建立小顶缀,已确认每次都取最小值:

 Queue<TreeNode> queue=new PriorityQueue<>(hs.size(), new Comparator<TreeNode>() {

            @Override
            public int compare(TreeNode o1, TreeNode o2) {
                return Integer.compare(o1.weight,o2.weight);
            }
        });

HashMap统计每个字符个数,以个数频率确认最少的字符,之后队列中先取建立哈夫曼树。

char[] chars = s.toCharArray();
        HashMap<Character,Integer> hs=new HashMap<>();
        for(int i=0;i<chars.length;i++){
            if(hs.containsKey(chars[i])){
                hs.put(chars[i],hs.get(chars[i])+1);
            }
            else {
                hs.put(chars[i],1);
            }
        }

将hashmap中的key,value放入queue;

for(Map.Entry<Character,Integer> a:hs.entrySet()){
            queue.offer(new TreeNode(a.getValue(),a.getKey()));
        }

queue出两个,建立一个父类TreeNode,放入queue,直到剩root;

while (queue.size()>1){
            TreeNode left = queue.poll();
            TreeNode right = queue.poll();
            TreeNode father=new TreeNode(left.weight+right.weight);
            father.left = left;
            father.right = right;
            queue.offer(father);
        }
        TreeNode root=queue.poll();

计算最少编码数count

public static int getcount(TreeNode node,int depth){
        if(node==null){
            return 0;
        }
        else {
            return (node.ch==null?0:node.weight)*depth+getcount(node.right,depth+1)+getcount(node.left,depth+1);
        }
    }

ok,就这样。自己组装叭。

猜你喜欢

转载自blog.csdn.net/qq_41076792/article/details/108503256
今日推荐