哈夫曼树的创建
哈夫曼树的创建是从下到上创建的,我这里是用一个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");
}
}
根据上边的输入会创建出来下面的这个二叉树