先构建一个结点类,其结构中包含有权值、双亲值、左孩子、右孩子、角标和Huffman编码。将数组里的数据,利用顺序表实现存储,调用Collections集合存放数据,调用其sort方法实现排序。然后选取其中最小的两个子树进行建立Huffman树。逆序计算Huffman编码,一次球1~n个结点对应的编码。建立一个临时存储Huffman编码的字符的数组,从的一个结点开始,通过该结点找到其双亲,若该结点是双亲的左孩子,则向数组输入为“0”,若是右孩子,则输入“1”。将临时数组中的值逆序输入到所求结点对应的二维数组中的那一行。这样就得到了所有结点的Huffman编码。
源码如下
public class Haff {
public static int number;
static List list;
public static void main(String[] args) {
list = new ArrayList();
out.println("请输入个数:");
Scanner scanner = new Scanner(System.in);
number = scanner.nextInt();
out.println("请输入权值:");
int[] wightness = new int[number];
for (int i = 0; i < wightness.length; ++i) {
wightness[i] = scanner.nextInt();
}
for (int i = 0; i < number; ++i) {
Node node = new Node(wightness[i], i);
list.add(node);
}
Collections.sort(list);
huffmanTree();
}
private static ArrayList selectTwoMin() {
ArrayList List = new ArrayList();
Integer first = 0, second = 0;
double small1, small2;
small1 = small2 = Double.MAX_VALUE;
for (int i = 0; i < list.size(); ++i) {
if (list.get(i).parent == -1) {
if (small1 > list.get(i).weight) {
second = first;
small2 = small1;
small1 = list.get(i).weight;
first = i;
} else if (small2 > list.get(i).weight) {
small2 = list.get(i).weight;
second = i;
}
}
}
List.add(first);
List.add(second);
return List;
}
public static void huffmanTree() {
for (int i = number; i < 2 * number - 1; i++) {
ArrayList min = selectTwoMin();
Integer first = min.get(0);
Integer second = min.get(1);
Node left = list.get(first);
Node right = list.get(second);
left.setParent(i);
right.setParent(i);
Node parent = new Node(left.weight+right.weight,i);
parent.setLchild(list.get(first).index);
parent.setRchild(list.get(second).index);
list.add(parent);
}
for (Node node : list) {
node.huffmanCode(list);
node.show();
}
}
}
public class Node implements Comparable{ public int parent; private int lchild; private int rchild; public double weight; public int index; public String code; public Node(double weight, int index) { super(); this.weight = weight; this.index = index; this.parent = -1; // 父节点初始化为-1,代表没有父节点 this.lchild = -1; // 左孩子初始化为-1,代表没有左孩子 this.rchild = -1; // 右结点初始化为-1,代表没有右孩子 this.code = ""; } public int compareTo(Node o) { if(this.weight < o.weight) return -1; else if(this.weight > o.weight) return 1; return 0; } public void show() { out.println("index wight rchild lchild code"); out.println(index+" "+weight+" "+rchild+" "+lchild+" "+code); } public void setLchild(int lchild) { this.lchild = lchild; } public void setRchild(int rchild) { this.rchild = rchild; } public void setParent(int parent) { this.parent = parent; } public void huffmanCode(List list) { int parent = this.parent; int index = this.index; while (parent != -1) { //结点的父节点为-1代表这个结点是根节点,树叶不断寻找父节点,由下向上求哈夫曼编码 if (list.get(parent).lchild == index) code += "0"; //如果树叶是树叶父节点的左孩子 else code += "1"; index = list.get(parent).index; parent = list.get(parent).parent; } StringBuffer reverse = new StringBuffer(); for (int i = code.length() - 1; i >= 0; --i) reverse.append(code.charAt(i)); code = reverse.toString(); } }



