1. 程式人生 > >哈夫曼編碼(自底向上的哈夫曼編碼)

哈夫曼編碼(自底向上的哈夫曼編碼)

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);
}