7-1 哈夫曼树
哈夫曼树,第一行输入一个数n,表示叶结点的个数。
需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出哈夫曼树的带权路径长度(WPL)。
输入格式:
第一行输入一个数n,第二行输入n个叶结点(叶结点权值不超过1000,2<=n<=1000)。
输出格式:
在一行中输出WPL值。
输入样例:
5
1 2 2 5 9
输出样例:
37
#include<iostream> #include<stdio.h> #include<string> #include<string.h> #include<cstring> #include<algorithm> #define MAX 0x3f3f3f3f using namespace std; typedef struct { int data; int weight; int parent; int lchild; int rchild; bool tag; int deep; }Huffnode,*HuffmanTree; HuffmanTree HT; int n; void Select(HuffmanTree &HT,int index, int &s1, int &s2) { int min1=MAX; int min2=MAX; for(int i=1;i<=index;++i) { if(HT[i].parent==0&&HT[i].tag) { if(HT[i].weight<min1) { s1=i; min1=HT[i].weight; } } } HT[s1].tag=0; for(int i=1;i<=index;++i) { if(HT[i].parent==0&&HT[i].tag) { if(HT[i].weight<min2) { s2=i; min2=HT[i].weight; } } } HT[s2].tag=0; } void CreatHuffmanTree(HuffmanTree &HT,int n) { if(n<=1)return; int m=2*n-1; HT=new Huffnode[m+1]; for(int i=1;i<=m;++i) { HT[i].data=0; HT[i].weight=0; HT[i].lchild=0; HT[i].rchild=0; HT[i].parent=0; HT[i].tag=1; HT[i].deep=0; } for(int i=1;i<=n;++i) { HT[i].data=i; scanf("%d",&HT[i].weight); } int s1,s2; for(int i=n+1;i<=m;++i) { Select(HT,i-1,s1,s2); HT[s1].parent=i; HT[s2].parent=i; HT[i].lchild=s1; HT[i].rchild=s2; HT[i].weight=HT[s1].weight + HT[s2].weight; HT[i].data=i; } } void Deep(int i) { for(int f=1;f<=n;++f) { int i=f; while(i!=2*n-1) { HT[f].deep++; i=HT[i].parent; } // cout<<HT[f].weight<<"的深度"<<HT[f].deep<<endl; } } int main() { cin>>n; CreatHuffmanTree(HT,n); for(int i=1;i<2*n-1;++i) { HT[i].tag=1; } Deep(1); int sum=0; for(int i=1;i<=n;++i) { sum+=HT[i].weight*HT[i].deep; } cout<<sum; // for(int i=0;i<2*n-1;++i) // { // cout<<HT[i].data<<"|"<<HT[i].weight<<"|"<<HT[i].deep<<"|"<HT[i].rchild<<"|"<<HT[i].lchild<<"|"; // cout<<HT[i].parent<<endl; // } }