哈弗曼编码C语言实现

//************************************
//本程序演示内容如下:
//1.哈弗曼编码[最优二叉树,采用顺序存储结构]
//2.二级指针使用
//3.函数内部使用malloc注意
//zping 2012-3-17
//************************************


#include<string.h> 
#include<stdlib.h> 
#include<stdio.h> 


int m,s1,s2;


typedef struct 
{ int weight; 
  int parent,lchild,rchild; 
}HuffmanTree;                 


void Select(HuffmanTree *HT,int n)     //选择最小两个权值的结点序号分别放在s1和s2
{
    int i,flag=0; 
    for(i = 1;i <= n;i++) 
    {
        if((!HT[i].parent) && (!flag))
        {
            s1=i;
            flag=1;
            continue;
        }
        if(HT[s1].weight>HT[i].weight && (!HT[i].parent))
            s1=i;
    }
    flag=0;
    for(i=1;i<=n;i++)
    {
        if((!HT[i].parent) && (!flag) && (i!=s1))
        {
            s2=i;
            flag=1;
            continue;
        }
        if(HT[s2].weight>HT[i].weight && (!HT[i].parent) && (i!=s1))
            s2=i;
    }







char **HuffmanCoding(HuffmanTree *HT, char **HC, int *w, int n) //构造函数建哈夫曼树并逆序构造编码
{


    int i; 
    char *cd; 
    int f,start,c; 


    if(n<=1) return NULL;       //若结点只有一个,则返回
    m = 2 * n - 1;               //计算总共节点个数
    HT = (HuffmanTree *)malloc((m+1) * sizeof(HuffmanTree));//给各个节点分配空间,下标从1开始所以多分配一个。
    for (i=1; i<=n; i++)          //初始化结点空间 
    { 
        HT[i].weight=w[i-1]; 
        HT[i].parent=0; 
        HT[i].lchild=0; 
        HT[i].rchild=0; 
    }  
    for (i=n+1; i<=m; i++)        //初始化辅助空间
    { 
        HT[i].weight=0; 
        HT[i].parent=0; 
        HT[i].lchild=0; 
        HT[i].rchild=0; 
    } 


    //构造哈夫曼树 
    for (i=n+1; i<=m; i++) 
    { 
        Select(HT, i-1); 
        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; 
    } 
    //构造哈夫曼编码 
    HC=(char **)malloc((n+1)*sizeof(char *));  //分配一个空间存储n个编码字符串的指针(多分配一个)
    cd=(char*)malloc((n+1)*sizeof(char));      //分配一个临时空间存储当前一个叶子节点的编码(多分配一个)
    cd[n-1]='\0';                               //从右向左逐位存放逆序编码[最终便是从左向右的顺序编码],首先存放编码结束符
    for(i=1;i<=n;i++)                          //开始求编码
    {
        start=n-1;      //初始化编码起始指针
        c=i;
        f=HT[i].parent;
        while(f!=0)
        {
            if( HT[f].lchild == c) 
                cd[--start]='0';  //左分支标0
            else 
                cd[--start]='1';  //右分支标1
            c=f;
            f=HT[f].parent; 
            HC[i]=(char *)malloc((n-start)*sizeof(char));  //为第i个编码分配空间
            strcpy(HC[i],&cd[start]);
        }
    }
    free(cd);
    return HC;      //此处要注意,本身HC是一个二级指针,在函数内部使用malloc分配了空间所以要返回该指针这是值传递;
                     //也可以使用三级指针采用引用传递,这时则不用返回了



 


int main(void) 

    HuffmanTree *HT;
    char **HC;
    int i, n=4;
   
    char chr[]={'a','b','c','d'};
    int w[] = {7,5,2,4};
  
    HC=HuffmanCoding(HT,HC,w,n); 
    printf("The HuffmanCode is:\n"); 
    for(i = 1;i <= n;i++)
    printf("%2d%5c%4d:  %s\n",i,chr[i-1],w[i-1],HC[i]); 
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值