哈夫曼树也称为最优二叉树,是指对于一组有确定权值的叶结点、构造的具有最小带权路径长度的二叉树。给你的问题是,提供一组n个整数权值,请你完成构建该组权值的哈夫曼树。
输入:标准输入,输入的第一行为一个正整数,其值代表需要构建二叉树的叶结点的个数n;输入的第二行为n个由一个空格隔开的正整数,表示叶结点的权值;输入的第三行为n个字符,对应第二行的权值的叶结点的名称;
输出:标准输出,输出构建的哈夫曼树的每个叶结点的访问路径,即从根到叶结点的路径,如果是走左输出l,如果走右输出r。每行输出一个叶结点信息,输出格式为:先输出该结点的名称,再输出冒号,接下来,输出路径,中间仅一个空格隔开。按照输入叶结点的名称次序分别使用n行输出。
测试样例:
输入:
4
7 5 3 1
abcd
输出:
a:l
b:r r
c:r l r
d:r l l
说明,为了进行系统判断,在构建哈夫曼树时,要求:
(1)选择两个权值小的结点在构建子树时,小的结点为左子树,较大的为右子树;
(2)如果存在两个权值相同,以出现的顺序依次为左右子树;
提示:
在构建哈夫曼树时,提供设计的结点对象参考如下:
public class HFMTreeNode {
int weight,parent,lchild,rchild;
HFMTreeNode(){
weight=0;
parent=lchild=rchild=-1;
}
}
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
HFMTree ht = new HFMTree();
ht.create();
ht.print();
}
}
class HFMTreeNode {
int weight,parent,lchild,rchild;
HFMTreeNode(){
weight=0;
parent=lchild=rchild=-1;
}
}
class HFMTree{
private HFMTreeNode[] data;
private int leafNum;
private String str;
public void create() {
Scanner sc = new Scanner(System.in);
leafNum = sc.nextInt();
data = new HFMTreeNode[2 * leafNum - 1];
for (int i = 0; i < 2 * leafNum - 1; ++i) {
data[i] = new HFMTreeNode();
}
for (int i = 0; i < leafNum; ++i) {
data[i].weight = sc.nextInt();
}
str = sc.next();
sc.close();
int data1, data2, index1, index2;
for (int i = 0; i < leafNum - 1; ++i) {
data1 = data2 = Integer.MAX_VALUE;
index1 = index2 = 0;
for (int j = 0; j < leafNum + i; ++j) {
if (data[j].weight < data1 && data[j].parent == -1) {
index2 = index1;
data2 = data1;
index1 = j;
data1 = data[j].weight;
} else if (data[j].weight < data2 && data[j].parent == -1) {
index2 = j;
data2 = data[j].weight;
}
}
data[index1].parent = leafNum + i;
data[index2].parent = leafNum + i;
data[leafNum + i].weight = data[index1].weight + data[index2].weight;
data[leafNum + i].lchild = index1;
data[leafNum + i].rchild = index2;
}
}
public void print() {
int[] id = new int[leafNum];
char[][] mp = new char[leafNum][leafNum];
for (int i = 0; i < leafNum; ++i) {
int tmp = i;
while (data[tmp].parent != -1) {
int last = tmp;
tmp = data[tmp].parent;
if (data[tmp].lchild == last) {
mp[i][id[i] ++] = 'l';
} else {
mp[i][id[i] ++] = 'r';
}
}
}
for (int i = 0; i < leafNum; ++i) {
System.out.print(str.charAt(i) + ":");
for (int j = id[i] - 1; j >= 0; --j) {
System.out.print(mp[i][j] + " ");
}
System.out.println();
}
}
}