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