简易哈夫曼树的创建(java)

哈夫曼树的创建

   哈夫曼树的创建是从下到上创建的,我这里是用一个list来存每个树节点,将list进行排序,依次拿到两个权值最小的结点,这个时候两个左右孩子就不在list集合中了,将他们作为一个新的双亲结点的左右孩子,然后将这个双亲加入到list集合中,重新进行排序。再拿到最小的两个结点作为左右孩子……这样最后list剩下的那一个就是根结点,将根结点返回就得到了树

哈夫曼树的编码

   定义一个字符串s,用它来记录这个编码,从根结点开始,如果是走根的左边,s就连接个0,如果是走根的右边,s就连接个1,当遇到叶子节点的时候这个s就是代表的这个叶子节点的编码。将叶子结点的val和它对应的编码输出就行。

import java.util.ArrayList;
import java.util.Scanner;

class Node {
    
    //树的结点
    int weight;
    Node Lchild;
    Node Rchild;
    Node parent;
    String val;
    public Node(){
    
    }
    public Node(String val,int weight) {
    
    
        this.weight = weight;
        this.val=val;
    }
}
public class HuffmanTree {
    
    
    public static void main(String[] args) {
    
    
        System.out.println("请输入字符集大小n:");
        Scanner sc=new Scanner(System.in);
        ArrayList<Node> list=new ArrayList<>();
        int n=sc.nextInt();
        ArrayList<String> res=new ArrayList<>();
        System.out.println("请输入字符及其出现的频率:");
        for(int i=0;i<n;i++) {
    
    
            String ch=sc.next();
            int weight=sc.nextInt();
            Node node=new Node(ch,weight);
            list.add(node);
        }
        //将树的结点按照weight的大小进行排序
       list.sort((o1, o2) -> o1.weight-o2.weight);
       //创建树
        Node root=CreateTree(list);
        String s="";
        print(root,s);
    }

    public static Node CreateTree(ArrayList<Node> list) {
    
    
        while(list.size()!=1) {
    
    
        	//获取到前两个结点
            Node temp1=list.remove(0);
            Node temp2=list.remove(0);
           	//new一个双亲结点
            Node par=new Node();
            //双亲结点的权值就是两个孩子的权值之和
            par.weight=temp1.weight+temp2.weight;
            //双亲结点的左右孩子就是前面的两个结点
            par.Lchild=temp1;
            par.Rchild=temp2;
            //前两个结点的双亲指针指向双亲结点
            temp1.parent=par;
            temp2.parent=par;
            //将双亲加入到list里面
            list.add(par);
            //重新按照weight排序
            list.sort((o1, o2) -> o1.weight-o2.weight);
        }
        //返回根结点
        Node node=list.get(0);
        return node;
    }

    public static void  print(Node root,String s) {
    
    
        if(root==null)
            return ;
        if(root.Rchild==null&&root.Lchild==null) {
    
    
        //走到叶子结点的时候
            System.out.println(root.val+":"+s);
        }
        //走左孩子,编码就是0
        print(root.Lchild,s+"0");
        //走右孩子,编码就是1
        print(root.Rchild,s+"1");
    }
}

根据上边的输入会创建出来下面的这个二叉树

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_51656756/article/details/121283102