huffman树的编码及应用

  最近写了huffman树的编码及应用的小程序,希望对各位网友有点帮助         

  在将树存储到文件的过程中,没有使用xml或者将2种遍历存储来确定唯一的树,我使用了类似与先序遍历的递归方式

gcc编译通过 ,  使用了一些linux的颜色的输出和系统调用 ,在 win的平台需要改下

 

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

#define Hashmax 26


typedef struct node{
    int weight;        /*表示权值*/
    char data;        /*表示字符*/
    char code[100]; /*表示该字符的huffman编码*/
    struct node *lchild,*rchild,*next;
}hufnode,*huftree;


/*用于建立散列表*/
typedef struct node2{   
    char key;
    char code[100];
}HashNode;


HashNode hashtab[Hashmax];        /*全局变量*/


void inithash()
{
    int i = 0;
    char c[100] = {'/0'};
    for (i = 0; i < Hashmax; i++){
        hashtab[i].key = '/0';
        strcpy(hashtab[i].code,c);
    }
}


int hash_mod(int key)
{
    return key % Hashmax;
}

void insert_hash(char key,char *code)
{
    int index;
    index = hash_mod(key);
    hashtab[index].key = key;
    strcpy(hashtab[index].code,code);
}



void showinterface()
{        printf("/n/n/n/n");
        printf("/t/t/t/t/33[33m 1  input  /n/33[37m");
        printf("/t/t/t/t/33[32m 2  save   /n/33[37m");
        printf("/t/t/t/t/33[31m 3  read   /n/33[37m");
        printf("/t/t/t/t/33[30m 4  code   /n/33[37m");
        printf("/t/t/t/t/33[34m 5  recode /n/33[37m");
        printf("/t/t/t/t/33[35m 6  exit   /n/33[37m");
}
   

huftree insert(huftree root, huftree s)
{
    huftree p1 = NULL, p2 = NULL;
    if (root == NULL)
        root = s;
    else{
        p1 = NULL;
        p2 = root;
        while (p2 && p2->weight < s->weight){
            p1 = p2;
            p2 = p2->next;
        }
        s->next = p2;
        if (p1 == NULL)
            root = s;
        else
            p1->next = s;
    }
    return root;
}



huftree createlist(huftree root, int size)
{
    huftree s = NULL;
    int i = 0;
    while (size-- > 0){
        s = (huftree)malloc(sizeof(hufnode));
        printf("/33[33m please input the weight of hufnode/n/33[37m");
        scanf("%d", &(s->weight));
        getchar();            /*接受回车*/
        printf("/33[33m please input the data of hufnode/n/33[37m");
        scanf("%c", &(s->data));
        getchar();
        s->lchild = s->rchild = s->next = NULL;
        root = insert(root, s);
    }
    return root;
}


huftree createhuffman(huftree root)
{
    int i = 0;
    huftree s = NULL, lc = NULL, rc = NULL;
    while (root && root->next){
        lc = root;
        rc = root->next;
        root = rc->next;
        lc->next = NULL;
        rc->next = NULL;
        s = (huftree)malloc(sizeof(hufnode));
        s->next = NULL;
        s->weight = lc->weight + rc->weight;
        s->data = '#';
        for (i = 0; i < 100; i++)
            lc->code[i] = rc->code[i] = s->code[i] = '/0';
        s->lchild = lc;
        s->rchild = rc;
        root = insert(root,s);
    }
    return root;
}

void inorder(huftree root)
{
    if (root){
        inorder(root->lchild);
        if(root->data != '#')
            printf("%c  %d  %s/t", root->data,root->weight,root->code);
        inorder(root->rchild);
    }
}


void save(huftree root, FILE *fp)
{
    if (root){
        fprintf(fp,"%c%d",root->data,root->weight);
        save(root->lchild, fp);
        fprintf(fp,"%c%d", '$',0);
        save(root->rchild, fp);
    }
    else{
        return;
    }
}
       

huftree rehuftree(int *i, int max, char *ad, int *aw)
{
    int j;
    if (*i < max){
        if (aw[*i] != 0 && ad[*i] != '$'){
            huftree tmp = (huftree)malloc(sizeof(hufnode));
            tmp->rchild = tmp->lchild = tmp->next = NULL;
            tmp->weight = aw[*i];
            tmp->data = ad[*i];
            /*将该节点编码置空*/
            for (j = 0; j < 100; j++)
                tmp->code[j] = '/0';
            (*i)++;
            tmp->lchild = rehuftree(i,max,ad,aw);
            (*i)++;
            tmp->rchild = rehuftree(i,max,ad,aw);
            return tmp;
        }
        else
            return NULL;
    }
    else
        return NULL;
}



/*载入文件中的数据*/
huftree load(FILE *fp)
{
    char ad[100]={'/0'};
    int aw[100];
    int i = 0;
    int max = 0;
    while (fscanf(fp,"%c%d",&ad[i],&aw[i])!=EOF){
        i++;
    }
    max = i;
    i = 0;
    return rehuftree(&i,max-1,ad,aw);
}

/*编码每个huffman树节点*/
void sethuffmanencoding(huftree root,char *t,int k)
{
    char tmp[100];
    int len = strlen(t);
    if (root){
        strcpy(root->code,t);
        if (k == 0)
            root->code[len] = '0';
        if (k == 1)
            root->code[len] = '1';
        sethuffmanencoding(root->lchild,root->code,0);
        sethuffmanencoding(root->rchild,root->code,1);
    }
    else
        return;
}


/*建立有序链表及huffman树*/
huftree Create(huftree root)
{
    int size = 0;
    while(size <= 0){
        printf("/33[33m please input the number of huffman tree/n/33[37m");
        scanf("%d",&size);
        if (size <= 0){
            printf("/33[33m please input the right number/n/33[37m");
            size = 0;
            continue;
        }
        else
            break;
    }

    root = createlist(root, size);
    root = createhuffman(root);
    return root;
}


/*输出编码*/
void outputcode(char key)
{
    int index = 0;
    if (key >= 'a' && key <= 'z'){
        index = hash_mod(key);
        if (hashtab[index].key == '/0')
            printf("no such key /n");
        else{
            printf("%s  ",hashtab[index].code);
        }
    }
    else
        printf("no such key /n");
}

/*编码*/
void code(huftree root, char *c)
{
    int i = 0;
    printf("/33[33m please input the string you want to code/n/33[37m");
    scanf("%s",c);
    while (c[i] != '/0'&& i < 100){
        outputcode(c[i]);
        i++;
    }
    printf("/n/n");
    getchar();
    getchar();
    return;
}

/*输出译码*/
void outputrecode(char *c,huftree root)
{
    int i = 0;
    printf("%s/t",c);
    while (*(c+i) != '/0'){
        if (root){
            if (*(c+i) == '0')
                root = root->lchild;
            else if (*(c+i) == '1')
                root = root->rchild;
        }
        i++;
    }
    if (root){
        if (strcmp(root->code,c) == 0 && root->data != '#'){
            printf("%c/n",root->data);
        }
        else
            printf("no such code/n");
    }
    else
        printf("no such code");
    getchar();
}


/*译码*/
void recode(huftree root)
{
    int i = 0;
    int j = 0;
    int n = 0;
    char c[100][100]={'/0'};
    if (root){
        printf("/33[33m please input the number of code you want to recode/n/33[37m");
        scanf("%d",&n);
        printf("/33[33m please input the recode/33[37m");
        for (j = 0; j < n; j++)
            scanf("%s",c[j]);
        while (i < n){
            outputrecode(c[i],root);
            i++;
        }
    }
    else{
        printf("/33[33m huffman tree is empty/n/33[37m ");
    }
    getchar();
    getchar();
    return;
}


void savecode(huftree root)
{
    int index;
    if (root){
        if(root->data >= 'a' && root->data <= 'z'){
            index = hash_mod(root->data);
            hashtab[index].key = root->data;
            strcpy(hashtab[index].code,root->code);
        }
        savecode(root->lchild);
        savecode(root->rchild);
    }
}



int main(int argc, char *argv[])
{
    FILE *fp;
    huftree root = NULL;
    char key='/0';
    char c[100]={'/0'};
    inithash();
    while(1){
        key = '/6';
        system("clear");
        showinterface();
        scanf("%c",&key);
        getchar();
        switch(key)
        {
            case '1':
                root = Create(root);
                sethuffmanencoding(root,"/0",-1);
                savecode(root);
                //inorder(root);
                break;
            case '2':
                if ((fp=fopen("htmTree","w"))==NULL){
                    printf("cannot open file");
                    exit(0);
                }                       
                save(root,fp);
                fclose(fp);
                break;
            case '3':
                if((fp=fopen("htmTree","r"))==NULL){
                    printf("cannot open file");
                    exit(0);
                }
                root = load(fp);
                fclose(fp);
                sethuffmanencoding(root,"/0",-1);
                savecode(root);
                inorder(root);
                break;
            case '4':
                code(root,c);
                break;
            case '5':
                recode(root);
                break;
            case '6':
                exit(0);
                break;
        }       
    }
    return 0;
}

 

阅读更多
个人分类: 编程
想对作者说点什么? 我来说一句

huffman树以及Huffman编码

2010年05月08日 365KB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭