北京邮电大学复试机试(2)

回眸只為那壹抹淺笑 提交于 2020-02-22 14:02:02

题目描述
哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。
输入描述:
输入有多组数据。
每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。
输出描述:
输出权值。
示例1
输入
5
1 2 2 5 9
输出
37
思路:
本体实际就是求带权路径长度

import java.util.*;

class Tree{
    int data;
    Tree left;
    Tree right;
    Tree(int data){
        this.data = data;
    }
}
public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        List<Tree> treeList = new ArrayList<Tree>();
        //构建N棵只有一个根节点的树
        for(int i=0;i < n;i ++){
            treeList.add(new Tree(input.nextInt()));
        }
        //构造哈夫曼树进行N-1次构造,删除合并操作
        for(int i = 0;i < n-1;i ++){
            createHuff(treeList);
        }
        //createHuff(treeList);
        int WPL = getWPL(treeList.get(0),0);
        System.out.println(WPL);
    }
    public static void createHuff(List<Tree> list){
        //重写排序规则,找出两个最小的树,合并为一个新的树 并添加进集合中 删除原来集合
        Collections.sort(list, new Comparator<Tree>() {
            @Override
            public int compare(Tree t1, Tree t2) {
                if(t1.data > t2.data){
                    return 1;
                }
                if(t1.data == t2.data){
                    return 0;
                }
                return -1;
            }
        });
        //找出最小的两棵树
        Tree t1 = list.get(0);
        Tree t2 = list.get(1);
        //合并两颗最小的树
        Tree t = new Tree(t1.data + t2.data);
        t.left = t1;
        t.right = t2;
        //将两个最小的树从集合中移除(因为已经构造了一个新的树)
        list.remove(t1);
        list.remove(t2);
        //将新的树添加进集合
        list.add(t);
    }
    public static int getWPL(Tree t,int n){
        if(t.left == null && t.right == null){
            return t.data * n;
        }
        return getWPL(t.left,n + 1) + getWPL(t.right,n + 1);
    }
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!