机试算法讲解: 第15题 霍夫曼树是啥树啊?

/*
问题:霍夫曼树
输入:第一行,输入一个数n,为叶节点个数,节点有权值weight
输出:所有节点的值与权值的乘积之和,2<=1000,weight<=100

输入:
5
1 2 2 5 9
输出:
37

思路:K个节点
K>=2,每次取最小值和次最小值,构成新节点,再放入
K=1,该节点为根节点,结束循环

关键:
1使用小顶堆,用priority_queue<int,vector<int>,qreater<int> >Q,以前使用<,将最小的放在前面
使用greater,即>,会将最大的放在前面,导致大顶堆
2使用权值累加:iSumWeight += iMin + iMin1
3要将新生成的节点放入到优先级队列中

*/


#include <stdio.h>
#include <stdlib.h>
#include <queue>
#include <memory.h>

using namespace std;

int main(int argc,char* argv[])
{
	int iNum;
	while(EOF!=scanf("%d",&iNum) && 2 <= iNum && iNum <= 1000)
	{
		priority_queue<int,vector<int>,greater<int> > Q;
		//做判空处理,如果为空先清空
		if(!Q.empty())
		{
			Q.pop();
		}
		//int *Arr = (int*)malloc(iNum*sizeof(int));
		int iValue;
		for(int i = 0 ;i < iNum ; i++)
		{
			scanf("%d",&iValue);
			if(iValue <= 100)
			{
				Q.push(iValue);
			}
			else
			{
				printf("The weight you input is wrong!");
			}
			//*(Arr + i) = iValue;
		}
		//进行堆操作,int count = 1,利用权值累加,例如:1,2,2 = (1+2) + 2 + 3,其中第一次的1 + 2已经累加了
		int iSumWeight = 0;
		while(1 < Q.size())
		{
			int iMin = Q.top();
			Q.pop();
			int iMin2 = Q.top();
			Q.pop();
			iSumWeight += iMin + iMin2;
			//把新的节点放入
			Q.push(iMin + iMin2);

		}
		printf("%d",iSumWeight);
	}
	system("pause");
	getchar();
	return 0;
}

你可能感兴趣的:(霍夫曼树,机试算法)