[原]哈弗曼编码(链表)

刘嘉辉 17/11/23 21:40:36

终于完成了初版的链表版 哈弗曼编码
效果如下
 这里写图片描述

/*************************************************************************
> 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);

}
作者:Holy_666 发表于2017/11/23 21:40:36 原文链接
阅读:4 评论:0 查看评论