基于C语言的赫夫曼编码的应用

来源:互联网 发布:淘宝退货没填快递单号 编辑:程序博客网 时间:2024/06/09 17:17

赫夫曼编码的应用

#include<stdio.h> #include<String.h>#define n 100#define m 2*n-1/*叶子的节点*/typedef struct{    char ch;    char bits[9];    int len;}CodeNode;typedef CodeNode HuffmanCode[n + 1];/*赫夫曼树的结构体*/typedef struct{    int weight;    int lchild, rchild, parent;}HTNode;typedef HTNode HuffmanTree[m + 1];int num;/*在HT的【1-K】中选择parent为0的权值最小的两个根据点*/void select(HuffmanTree T, int k, int *s1, int *s2){    int i, j;    int min1 = 101;    for (i = 1; i <= k; i++)    {        j = i;        min1 = T[i].weight;    }    *s1 = j; min1 = 32767;    for (i = 1; i <= k; i++)        if (T[i].weight<min1 && T[i].parent == 0 && i != *s1)        {            j = i;            min1 = T[i].weight;        }    *s2 = j;}/*统计字符串中各种字母的个数以及字符的总类*/int jsq(char *s, int cnt[], char str[]){    char *p;    int i, j, k;    int temp[27];    for (i = 1; i <= 26; i++)        temp[i] = 0;    for (p = s; *p != '\0'; p++)    {        if (*p >= 'A' && *p <= 'Z')        {            k = *p - 64;            temp[k]++;        }    }    for (i = 1, j = 0; i <= 26; i++)        if (temp[i] != 0)        {            j++;            str[j] = i + 64;            cnt[j] = temp[i];        }    return j;}/*构造赫夫曼树HT*/void ChuffmanTree(HuffmanTree HT, HuffmanCode HC, int cnt[], char str[]){    int i, s1, s2;    for (i = 1; i <= 2 * num - 1; i++)    {        HT[i].lchild = 0;        HT[i].rchild = 0;        HT[i].parent = 0;        HT[i].weight = 0;    }    for (i = 1; i <= num; i++)        HT[i].weight = cnt[i];    for (i = num + 1; i <= 2 * num - 1; 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;    }    for (i = 0; i <= num; i++)        HC[i].ch = str[i];    i = 1;    while (i <= num)    printf("字符 %c,次数为:%d\n", HC[i].ch-1, cnt[i++]);}/*根据赫夫曼树HT求赫夫曼编码表HC*/void HuffmanEncoding(HuffmanTree HT, HuffmanCode HC){    int c, p, i;    char cd[n];    int start;    cd[num] = '\0';    for (i = 1; i <= num; i++)    {        start = num;        c = i;        while ((p = HT[c].parent)>0)        {            cd[--start] = (HT[p].lchild == c) ? '0' : '1';            c = p;        }        strcpy(HC[i].bits, &cd[start]);        HC[i].len = num - start;    }}/*对str所代表的字符串进行编码,并写入文件*/void coding(HuffmanCode HC, char *str){    int i, j;    FILE *fp;    fp = fopen("codefile.txt", "w");    while (*str)    {        for (i = 1; i<=num; i++)            if (HC[i].ch == *str)            {                for (j = 0; j<HC[i].len; j++)                    fputc(HC[i].bits[j], fp);                break;            }        str++;    }    fclose(fp);}/*代码文件codefile.txt的译码*/char *decode(HuffmanCode HC){    FILE *fp;    char str[254];    /*假设原文本文件不超过254个字符*/    char *p;    static char cd[n + 1];    int i, j, k = 0, cjs;    fp = fopen("codefile.txt", "r");    while (!feof(fp))    {        cjs = 0;        for (i = 0; i<num && cjs == 0 && !feof(fp); i++)        {            cd[i] = ' ';            cd[i + 1] = '\0';            cd[i] = fgetc(fp);            for (j = 1; j<num; j++)            {                if(strcmp(HC[j].bits,cd)==0)                {                       str[k] = HC[j].ch;                    k++;p;                    cjs = 1;                    break;                }            }        }    }}/*主函数*/int main(void){    char str[27];    char st[254], *s;    int cn[27];    HuffmanTree HT;    HuffmanCode HC;    printf("输入需要编码的字符串(假设均为大写字母):\n");    gets(st);    num = jsq(st, cn, str);    ChuffmanTree(HT, HC, cn, str);    HuffmanEncoding(HT, HC);    coding(HC, st);    s = decode(HC);    printf("编译后的字符串:\n");    printf("%s\n", s);}
原创粉丝点击