Huffman代码实现

来源:互联网 发布:淘宝联盟可以合并下单 编辑:程序博客网 时间:2024/06/10 22:40


#include <stdio.h>#include <malloc.h>#include <string.h>typedef unsigned int u32;typedef int status;#define OK    1#define ERROR 0#define N 4#define UINT_MAX 65535/* huffman 算法用数组来表示树,设置父节点目的是用于从叶子节点到根编码 */struct htnode{    u32 weight;#if 0     struct htnode *lchild;    struct htnode *rchild;      sturct htnode *father;#endif    int lchild;    int rchild;    int father; };void select(struct htnode *HT , int n, int *s1, int *s2) {    int i;    u32 weight = UINT_MAX;        for (i = 1; i <= n; i++)    {        if ((HT[i].father == 0) && (HT[i].weight < weight))        {            weight = HT[i].weight;            (*s1) = i;        }    }    weight = UINT_MAX;    for (i = 1; i <= n; i++)    {        if (i == (*s1))        {            continue;        }        if ((HT[i].father == 0) && (HT[i].weight < weight))        {            weight = HT[i].weight;            (*s2) = i;        }    }}/* 申请n+1个空间,实际上只用了n个。第0个不用是为了保持阅读代码清晰简便 */status huffman_code(struct htnode **HT, char ***hc, int *w, int n){    int i;    int m;    int s1,s2;    int c,f;    char *cd;    int start;        m = 2 * n - 1;    (*HT) = (struct htnode*)malloc(sizeof(struct htnode) * (m + 1));    if (!(*HT))    {        printf("%s: malloc failed\n", __FUNCTION__);        return ERROR;    }    for (i = 1; i <= n; i++)    {       (*HT)[i].weight = w[i];        (*HT)[i].lchild = 0;       (*HT)[i].rchild = 0;       (*HT)[i].father = 0;    }    for (i = n + 1; i <= m; i++)    {       (*HT)[i].weight = 0;        (*HT)[i].lchild = 0;       (*HT)[i].rchild = 0;       (*HT)[i].father = 0;    }    for (i = n + 1; i <= m; i++)    {       select(*HT, i - 1 , &s1, &s2);        printf("s1 = %d, s2 = %d\n", s1, s2);       (*HT)[s1].father = i;       (*HT)[s2].father = i;       /* 此处不要写成w[s1] + w[s2]了 */       (*HT)[i].weight = (*HT)[s1].weight + (*HT)[s2].weight;         (*HT)[i].lchild = s1;       (*HT)[i].rchild = s2;    }    *hc = (char**) malloc(sizeof(char *) * (n + 1));    if (!(*hc))    {        printf("%s: malloc failed\n", __FUNCTION__);        return ERROR;    }    /* n个节点的编码长度最多为n-1,但留一个给'\0'作字符串结束 */    cd = (char*)malloc(sizeof(char) * (n - 1 + 1));    cd[n-1] = '\0';    for (i = 1; i <= n; i++)    {        start = n-1;        for (c = i,f = (*HT)[c].father; f != 0; c = f,f = (*HT)[c].father)         {           if ((*HT)[f].lchild == c)            {               cd[--start] = '0';           }           else           {               cd[--start] = '1';           }        }        /* 多留一个字节给'\0'使用 */        (*hc)[i] = (char *)malloc(sizeof(char) * (n - 1 - start + 1)); 
        if (!(*hc)[i])        {            printf("%s: malloc failed\n", __FUNCTION__);            return ERROR;        }        strcpy((*hc)[i], &cd[start]);    }}void print_code(char **HC, int *w, int n){    int i;    for (i = 1; i <= n; i++)    {        printf("the %d char(weight(%d))'s code is %s\n", i, w[i], HC[i]);      }}int main(void){    struct htnode *HT;    char **HC;    int n = N;    int w[N+1] = {-1, 3, 5, 2, 7};    huffman_code(&HT, &HC, w, n);     print_code(HC, w, n);}

原创粉丝点击