北京郵電大學複試機試(2)

題目描述
哈夫曼樹,第一行輸入一個數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);
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章