您的位置:首页 > 其它

【九度OJ-1172】 哈夫曼数

2017-07-26 20:40 211 查看
九度oj地址:http://ac.jobdu.com/problem.php?pid=1172

时间限制:1 秒

内存限制:32 兆

特殊判题:否

提交:8168

解决:3641

题目描述:

哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。

输入:

输入有多组数据。

每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。

输出:

输出权值。

样例输入:
5
1 2 2 5 9


样例输出:
37


来源:2010年北京邮电大学计算机研究生机试真题

第一种方法:不建树,这种方法要简单一点

[cpp] view
plain copy

#include <stdio.h>  

#include <string.h>  

#include <algorithm>  

#include<iostream>  

#include<stack>  

using namespace std;  

int result[1001];  

//哈夫曼树的权值就是除了所有叶子  

//的节点的权值的和  

int main(){  

    int n,i,sum,num;  

    while(scanf("%d",&n)!=EOF){  

        memset(result,0,n);  

        for(i=0;i<n;i++)  

            scanf("%d",&result[i]);  

        //进行排序,从小到大  

        sort(result,result+n);  

        i=1;  

        sum=0;  

        while(i<n){  

            //每次都要进行重新排序,因为生成了新的节点  

           sort(result+i-1,result+n);  

           //计算父亲  

           num = result[i-1]+result[i];  

           sum+=num;  

           //将新的节点赋值  

           result[i]=num;  

           i++;  

        }  

        printf("%d\n",sum);  

    }  

    return 0;  

}  

第二种方法:建树

[cpp] view
plain copy

  

[cpp] view
plain copy

<pre name="code" class="cpp">#include <stdio.h>  

#include <string.h>  

#include <algorithm>  

#include<iostream>  

#include<stack>  

#define maxvalue 0x7fffffff//这个是int的最大值  

using namespace std;  

//创建节点的结构体  

struct huffman{  

    int weight;  

    int parent,lchild,rchild;  

}list[5000];  

int main()  

{  

    int n,m;  

    int i,j;  

    int ans;  

    int x1,x2;//用来存放树生成过程中的最小和次小的角标  

    int m1,m2;//用来存放树生成过程中的最小和次小的值  

    while(scanf("%d",&n)!=EOF)  

    {  

        m=2*n-1;  

        for(i=0;i<m;i++)  

        list[i].parent=list[i].lchild=list[i].rchild=-1;  

        for(i=0;i<n;i++)  

        scanf("%d",&list[i].weight);  

        ans=0;  

        for(i=0;i<n-1;i++){  

            x1=x2=0;  

            m1=m2=maxvalue;  

            for(j=0;j<n+i;j++){  

                //用来判断新的节点是否小于最小且没有双亲  

                //如果小于最小的话就把当前的数和角标给x1和m1  

                //并且在x1和m1中存入当前最小的角标和值  

                if(list[j].weight<m1&&list[j].parent==-1){  

                    x2=x1;  

                    m2=m1;  

                    x1=j;  

                    m1=list[j].weight;  

                }  

               //用来判断是不是小于次小,如果小于的话就替换次小  

                else if(list[j].weight<m2&&list[j].parent==-1){  

                    x2=j;  

                    m2=list[j].weight;  

                }  

            }  

            list[x1].parent=n+i;  

            list[x2].parent=n+i;  

            list[n+i].lchild=x1;  

            list[n+i].rchild=x2;  

            list[n+i].weight=list[x1].weight+list[x2].weight;  

            ans+=list[n+i].weight;  

        }  

        printf("%d\n",ans);  

    }  

    return 0;  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  哈夫曼树