哈弗曼編碼(鏈表)

終於完成了初版的鏈表版 哈弗曼編碼
效果如下
 這裏寫圖片描述

/*************************************************************************
> File Name: huff.c
> Author:劉嘉輝 
> Mail: 
> Created Time: 2017年11月20日 星期一 21時11分48秒
************************************************************************/

#include<stdio.h>
#include<stdlib.h>
typedef  struct node {
    char a;
    int  weight;
    struct node  *left;
    struct node  *right;

}Htree;
typedef struct ch{
    char c;
    int  *pp;
}Node;
//創建哈弗曼樹
Htree * create_tree(int A[]  ,int  n)
{
    Htree *q;
    Htree **B; //存放葉子節點的數組

    int  min=-1,next_min;

    //將數據存儲在空間裏
    int i ,j;
    B = (Htree **) malloc(n*sizeof(Htree *));
    for (  i=0 ;i<n;i++){
        B[i] = (Htree *)malloc(sizeof(Htree) ) ;
        B[i]->weight = A[i];
        B[i]->left = B[i]->right = NULL;

    }
    //循環n-1次進行建立哈弗曼樹

    for(i=1; i<n ; i++){
       min=-1;
//        next_min;
        //對最小 次小進行初始化
        for(j=0;j<n;j++){
            if(B[j]!= NULL && min == -1  )  //特別要注意條件的設置
            {
                min = j;
                continue;
            }
            if(B[j]!=NULL)
            {
                next_min = j;
                break;
            }
        }
        //遍歷整個數組找出最小和次最小 以下有兩種方式
        /*  
        int temp;
        if (B[min]->weight > B[next_min]->weight) {
            temp=min;min=next_min;next_min=temp;
        }
        //printf("min=%d next_min=%d\n",min,next_min );
        for(j=0;j<n;j++)
        {
            if(B[j] != NULL ){
                if( B[j]->weight < B[min]->weight )
                {
                    next_min=min;
                    min=j;
                } else if (B[j]->weight<B[next_min]->weight && j!=min) {
                    next_min=j;
                }

            }
        }
        */
        for  (j = next_min ; j<n; j++)
        {
            if(B[j] != NULL )
            {
                if(B[j]->weight < B[min]->weight )
                {
                    next_min = min;
                    min = j;    //首次時相當於min和 next_min發生了交換 非常精簡

                }    
                else if(B[j]->weight < B[next_min]->weight )
                    next_min = j;
            }
        }


        //生成新節點進行賦值
        q = (Htree *) malloc (sizeof(Htree));
        q->weight = B[min]->weight + B[next_min]->weight;
        q->left = B[min];
        q->right = B[next_min];

        B[min] = q;
        B[next_min] = NULL;

        for(int  k =0;k<n;k++)
        {
            if(B[k])
                printf("%d ",B[k]->weight);
            else
                printf("NULL ");
        }

        printf("\n");

    }
    free(B);
    return q;
}
void visit_Htree(Htree *TT)
{
    if(TT != NULL)
    {
        printf("%d ",TT->weight );
        visit_Htree(TT->left);
        visit_Htree(TT->right);

    }

}
//哈弗曼編碼
void Huffmancoding(Htree *TT,int  len)
{
    static int code[10];
    if(TT != NULL)
    {
        if(TT->left == NULL && TT->right ==NULL)
        {
            printf("%d 處的哈弗曼編碼爲:",TT->weight);
            int  j=0;
            for ( j= 0;j<len;j++)
                printf("%d", code[j]);
            printf("\n");


        }
        else  //進入節點之後 進左右之前分別存儲0或1
        {
            code[len] = 0;
            Huffmancoding(TT->left, len+1);
            code[len] = 1;
            Huffmancoding(TT->right, len+1);
        }

    }
}

int main ()
{
    Htree *TT;
    //申請存放權值的空間
    int *A;
    int n;
    while (1){
        scanf("%d",&n);
        if(n  > 1)
        break;
    }
    A = (int *) malloc(sizeof(int) * n);
    for (int i=0; i<n ; i++){
        scanf("%d",& A[i]);
    }



    //創建哈弗曼樹  還需加一條字符數組進行辨認
    TT = create_tree(A,n);
    visit_Htree(TT);
    printf("\n");
    //哈弗曼編碼
    Huffmancoding(TT,0);

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章