Description

本题中,读入n个字符所对应的权值,生成赫夫曼编码,并依次输出计算出的每一个赫夫曼编码。

Input

输入的第一行包含一个正整数n,表示共有n个字符需要编码。其中n不超过100。
第二行中有n个用空格隔开的正整数,分别表示n个字符的权值。

Output

共n行,每行一个字符串,表示对应字符的赫夫曼编码。

Sample Input

8
5 29 7 8 14 23 3 11

Sample Output

0110
10
1110
1111
110
00
0111
010

HINT

赫夫曼树又名最优二叉树,它是一类带权路径长度最小的二叉树。通过构造赫夫曼树,我们可以得到赫夫曼编码,从而使得通信能够得到更高的效率。在本题中,构造赫夫曼树的过程使用了从叶子到根的逆向顺序,另外,还有一种从根出发直到叶子的赫夫曼编码构造算法

 

代码

/**************************************************************
    Problem: 2610
    User: 201717010009
    Language: C
    Result: Accepted
    Time:0 ms
    Memory:1096 kb
****************************************************************/
#include<stdio.h>
#include<malloc.h>
#include<string.h>
typedef struct {
    int weight;
    int parent;
    int lchild;
    int rchild;
}HTNode,*HuffmanTree;
void Select(HTNode HT[],int n,int *s1,int *s2)
{
    int min1=10000,min2=10000;
    for(int i=1;i<=n;i++)
    {
        if(HT[i].weight<min1&&HT[i].parent==0)
        {
            min1=( HT[i].weight );
            *s1=i;
        }
    }
    HT[*s1].parent=1;//找到最小的  使父节点不为0 
    for(int i=1;i<=n;i++)
    {
        if(HT[i].weight<min2&&HT[i].parent==0)
        {
            min2=( HT[i].weight );
            *s2=i;
        }
    }
    HT[*s2].parent=1;//
    int j;
    if(*s1>*s2)
    {
        j=*s1;
        *s1=*s2;
        *s2=j;
    }
}
void HuffmanCoding(int *w,int n)
{
    if(n<=1)
    return;
    int m=2*n-1;
    HTNode HT[m+1];
    HuffmanTree p;
    int i;
    for(p=&HT[1],i=1;i<=n;i++,p++,w++)//初始化1到n 
    {
        p->weight=*w;
        p->lchild=0;
        p->rchild=0;
        p->parent=0;
    }
    for(;i<=m;i++,p++)//初始化n+1到m 
    {
        p->lchild=0;
        p->parent=0;
        p->rchild=0;
        p->weight=0; 
    }
    int s1=0,s2=0;
    for(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;
    }
    char HC[n+1][n];
    for(i=1;i<=n;i++)
    {
        char cd[n];
        cd[n-1]='\0';
        int start=n-1,c,f;
        for(c=i, f=HT[i].parent; f!=0; c=f, f=HT[f].parent)
        {
            if(HT[f].lchild==c)
            {
                start--;
                cd[start]='0';
            }
            else
            {
                start--;
                cd[start]='1';
            }
        }
        strcpy(HC[i],&cd[start]);//从start处开始  直到最后  复制到 HC里 
    }
    for(int j=1;j<=n;j++)
    {
        printf("%s",HC[j]);
        printf("\n");
    }
}
 
int main()
{
    int n;
    scanf("%d",&n);
    int a[n];
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    int *w=&a[0];
    HuffmanCoding(w,n);
}