刷题蓝桥杯(java)---Huffman树

/*问题描述
   Huffman树在编码中有着广泛的应用。在这里,我们只关心Huffman树的构造过程。
   给出一列数{pi}={p0, p1, …, pn-1},用这列数构造Huffman树的过程如下:
   1. 找到{pi}中最小的两个数,设为pa和pb,将pa和pb从{pi}中删除掉,然后将它们的和加入到{pi}中。这个过程的费用记为pa + pb。
   2. 重复步骤1,直到{pi}中只剩下一个数。
   在上面的操作过程中,把所有的费用相加,就得到了构造Huffman树的总费用。
   本题任务:对于给定的一个数列,现在请你求出用该数列构造Huffman树的总费用。

  例如,对于数列{pi}={5, 3, 8, 2, 9},Huffman树的构造过程如下:
   1. 找到{5, 3, 8, 2, 9}中最小的两个数,分别是2和3,从{pi}中删除它们并将和5加入,得到{5, 8, 9, 5},费用为5。
   2. 找到{5, 8, 9, 5}中最小的两个数,分别是5和5,从{pi}中删除它们并将和10加入,得到{8, 9, 10},费用为10。
   3. 找到{8, 9, 10}中最小的两个数,分别是8和9,从{pi}中删除它们并将和17加入,得到{10, 17},费用为17。
   4. 找到{10, 17}中最小的两个数,分别是10和17,从{pi}中删除它们并将和27加入,得到{27},费用为27。
   5. 现在,数列中只剩下一个数27,构造过程结束,总费用为5+10+17+27=59。
 输入格式
   输入的第一行包含一个正整数n(n<=100)。
   接下来是n个正整数,表示p0, p1, …, pn-1,每个数不超过1000。
 输出格式
   输出用这些数构造Huffman树的总费用。
 样例输入
 5
 5 3 8 2 9
 样例输出
 59
*/
import java.util.Scanner;
class huffman {
	int weight;
	int lnode;
	int rnode;
	int parent;

}
class Main {
	

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int sum = 0;
		huffman[] ht = new huffman[2 * n - 1];
		int min1, min2, lnode, rnode;
		for (int i = 0; i < 2 * n - 1; i++) {// 初始化parent为-1
			ht[i] = new huffman();
			ht[i].parent = ht[i].lnode = ht[i].rnode = -1;
			if (i < n)
				ht[i].weight = in.nextInt();
		}
		for (int i = n; i < 2 * n - 1; i++) {//叶子结点为N的二叉树,有2n-1个节点,前n个为数列,后n-1为空,作parent
			min1 = min2 = 1001;//题目要求,数列大小不超过1000
			lnode = rnode = -1;
			for (int k = 0; k <= i - 1; k++) {//i作为parent
				if(ht[k].parent==-1) {
					if (ht[k].weight < min1) {//找到两个最小的数
						min2 = min1;
						rnode = lnode;
						min1 = ht[k].weight;
						lnode = k;
					} else if (ht[k].weight < min2) {
						min2 = ht[k].weight;
						rnode = k;
					}
				}
			}
			//赋值孩子父母
			ht[i].lnode = lnode;
			ht[i].rnode = rnode;
			ht[i].weight = ht[rnode].weight + ht[lnode].weight;
			ht[rnode].parent = ht[lnode].parent = i;
			sum += ht[i].weight;
		}
		System.out.println(sum);

	}
}

你可能感兴趣的:(java)