Loading

9、哈夫曼树的实现

    哈夫曼树也称为最优二叉树,是指对于一组有确定权值的叶结点、构造的具有最小带权路径长度的二叉树。给你的问题是,提供一组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();
        }
    }
}

posted @ 2022-12-10 18:38  qing影  阅读(39)  评论(0)    收藏  举报  来源