创建哈夫曼树

  • 首先找到每一个字母出现的次数作为该字母的权重
    在这里插入图片描述
  • 然后每一次找权重最小的两个构建哈夫曼树,把新生成的节点加到原列表中
  • 再选择两个最小值的形成新的数
    在这里插入图片描述

构建好了之后按照左0右1的原则给字符串进行编码,由此编码可以读出该字符串

package com.qcby.Tree;

public class Node {
    private String ch;
    private int num;
    private Node left;
    private Node right;

    public Node(String ch, int num) {
        this.ch = ch;
        this.num = num;
    }

    public Node() {
    }


    public String getCh() {
        return ch;
    }

    public void setCh(String ch) {
        this.ch = ch;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public Node getLeft() {
        return left;
    }

    public void setLeft(Node left) {
        this.left = left;
    }

    public Node getRight() {
        return right;
    }

    public void setRight(Node right) {
        this.right = right;
    }

    @Override
    public String toString() {
        return "Node{" +
                "ch='" + ch + '\'' +
                ", num=" + num +
                ", left=" + left +
                ", right=" + right +
                '}';
    }
}

package com.qcby.Tree;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class MyHuffman {
    public static void main(String[] args) {
        String str="ajsfhsdhfasdfkjhsdfhsalkdjsfhdsfhjsklasjfjksfdghkslkdahjfjhsdgasjfhsdjfjshhfg";

        //统计每个字母出现的次数
        HashMap<String ,Integer> map=new HashMap<>();
        for(int i=0; i<str.length();i++){
            String ch=str.charAt(i)+"";
            if(map.get(ch)==null){
                map.put(ch,1);
            }else {
                map.put(ch,map.get(ch)+1);
            }
        }
        //把这些节点加入一个集合中
        ArrayList<Node> arr=new ArrayList<>();
        for(Map.Entry<String ,Integer> en:map.entrySet()){
            System.out.println("key:  "+en.getKey()+"   value:"+en.getValue());
            Node node=new Node(en.getKey(),en.getValue());
            arr.add(node);
        }
        for (;;){
            if(arr.size()>1){
                Node[] data=getNode(arr);
                Node root=new Node(null,data[0].getNum()+data[1].getNum());
                root.setLeft(data[0]);
                root.setRight(data[1]);
                arr.add(root);
            }else
                break;
        }
        Node tree = arr.get(0);  //TREE就是最终的哈夫曼树
        Map<String,String> charMaps = new HashMap<>();//key是字符
        Map<String,String> codeMaps = new HashMap<>();

        allShow(tree,"", charMaps, codeMaps);
        String hafucode = "";
        for(int i = 0; i < str.length(); i++) {

            String ch  = str.charAt(i) + "";
            hafucode += charMaps.get(ch);
        }
        System.out.println( hafucode.length() + "||" + str.length() );
        System.out.println( hafucode );

        String res="";
        while (hafucode.length()>0){
            for(Map.Entry< String,String> entry:codeMaps.entrySet()){
                if(hafucode.startsWith(entry.getKey())){
                    res+=entry.getValue();
                    hafucode=hafucode.substring(entry.getKey().length());
                }
            }
        }
        System.out.println(res);



    }
    //找到这个集合中最小的两个值
    public static Node[] getNode(ArrayList<Node> arr){
        Node[] nos=new Node[2];
        int index1;
        int index2;
        index1=arr.get(0).getNum()<=arr.get(1).getNum()?0:1;
        index2=arr.get(0).getNum()<=arr.get(1).getNum()?1:0;
        for(int i=2;i<arr.size();i++){
            if(arr.get(i).getNum()<arr.get(index1).getNum()){
                index2=index1;
                index1=i;
            }else if(arr.get(i).getNum()<arr.get(index2).getNum() && arr.get(i).getNum()>=arr.get(index1).getNum()){
                index2=i;
            }
        }
        nos[0]=arr.get(index1);
        nos[1]=arr.get(index2);
        arr.remove(index1);
        if(index1<index2){
            arr.remove(index2-1);
        }else {
            arr.remove(index2);
        }
        return nos;
    }
    public static void allShow(Node tree,String code, Map<String,String> charMaps ,  Map<String,String> codeMaps){

        if(tree.getLeft()==null){
            System.out.println(tree.getNum()+"-------->code"+code);
            charMaps.put(tree.getCh(), code);
            codeMaps.put(code, tree.getCh());
        }else {
            allShow(tree.getLeft(),code+"0",charMaps,codeMaps);
            allShow(tree.getRight(),code+"1",charMaps,codeMaps);
        }
        /*if(tree==null){
            return;
        }else {
            /*先序遍历
            System.out.println(tree.getNum());
            allShow(tree.getLeft());
            allShow(tree.getRight());*/
            //输出叶子节点
            /*if(tree.getLeft()==null&&tree.getRight()==null){
                System.out.println(tree.getNum());

            }else {
                allShow(tree.getLeft());
                allShow(tree.getRight());
            }
        }*/

    }
}

原创文章 55 获赞 55 访问量 5772

猜你喜欢

转载自blog.csdn.net/weixin_45007916/article/details/106129243