0
点赞
收藏
分享

微信扫一扫

7-2 哈夫曼编码译码(25分)(c语言)

7-2 哈夫曼编码译码(25分)(部分思路和代码)


@Sparks
2022-03-05
gxust的数据结构实验

题目

编写一个哈夫曼编码译码程序。

按词频从小到大的顺序给出各个字符(不超过30个)的词频,根据词频构造哈夫曼树,给出每个字符的哈夫曼编码,并对给出的语句进行译码。

为确保构建的哈夫曼树唯一,本题做如下限定:

(1)选择根结点权值最小的两棵二叉树时,选取权值较小者作为左子树。

(2)若多棵二叉树根结点权值相等,按先后次序分左右,先出现的作为左子树,后出现的作为右子树。

生成哈夫曼编码时,哈夫曼树左分支标记为0,右分支标记为1。

输入格式:
第一行输入字符个数n;

第二行到第n行输入相应的字符及其词频(可以是整数,与可以是小数);

最后一行输入需进行译码的串。

输出格式:
首先按树的先序顺序输出所有字符的编码,每个编码占一行;

最后一行输出需译码的原文,加上original:字样。

输出中均无空格

输入样例:

输出样例:

分析

关键就是哈夫曼编码的构造和译码,但是这里有一个难点:分离字符和数字,还有数字不只有整数还有浮点数

代码

因为某些原因我不能提供完整代码,具体实现还是要靠各位同学思考和调试。
注释很少是因为我一路写下来的,没怎么注释,代码只能参考,毕竟我也是花了很多时间才写出来的

#include<stdio.h>
#include<stdlib.h>
#define MAXVALUE 32767
typedef struct hf{//哈夫曼树
    int weight;
    int parent;
    int lchild;
    int rchild;
}Htree;

typedef struct hc{//哈夫曼编码
    int* bit;//存放当前结点的哈夫曼编码
    int start;//bit[start]-bit[n]存放哈夫曼编码
    char ch;
}Hcode;




Htree* InitHtree(int* w,int leght){
    int i;
    Htree* HT = (Htree*)malloc(sizeof(Htree)*(2*leght-1));
    for(i = 0; i<leght; i++){
        HT[i].weight = w[i];
        HT[i].parent = -1;
        HT[i].lchild = -1;
        HT[i].rchild = -1;
        }
        return HT;
}

Hcode* InitHcode(int leght,char* ch){
    int i;
    Hcode* HC = (Hcode*)malloc(sizeof(Hcode)*leght);

    for(i = 0; i<leght; i++){
        HC[i].bit = (int*)malloc(sizeof(int)*leght);
        HC[i].ch = ch[i];
    }
    
    return HC;
}


void CreateHuffTree(Htree* HT,int leght){			//构造哈夫曼树
    int i,j,a,b,min1,min2;
    int l = 2*leght-1;
    for(i = leght;i<l;i++){
        a = MAXVALUE;
        b = MAXVALUE;
        min1 = 0;
        min2 = 0;
            for(j = 0; j < leght+i; j++){ //选取最小的权值
                if(HT[j].parent == -1 && HT[j].weight < a){
                    a = HT[j].weight;
                    min1 = j;
                }
            }
        for(j = 0; j < leght+i; j++){ //选取次小的权值
                 if(HT[j].parent == -1 && HT[j].weight < b && j!= min1){
                    b = HT[j].weight;
                    min2 = j;
                }
            }

        HT[i].weight = HT[min1].weight+HT[min2].weight;
        HT[i].parent = -1;
        HT[i].lchild = min1;
        HT[i].rchild = min2;
        HT[min1].parent = i;
        HT[min2].parent = i;
       
        leght++;//没有必要。

    }

}
void PrintHuffTree(Htree* HT,Hcode* HC,int index,int leght){//输出哈夫曼树
 

     int i;
     printf("\n哈夫曼树各项数据如下表所示:\n");
	 printf("        结点i weight parent    lchid    rchild\n");
	 for(i=0;i<index;i++){
        printf("\t%d\t%d\t%d\t%d\t%d\n",i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);

     }




}		
void CreateHuffCode(Hcode* HC,Htree* HT,int leght){//构造哈夫曼编码
    
    int i,j,c,p;
    
    for(i = 0; i<leght;i++){
        Hcode* cd = (Hcode*)malloc(sizeof(Hcode));
        cd->bit = (int*)malloc(sizeof(int)*leght);
        cd->start = leght-1;
        c = i;
        p = HT[c].parent;

        while(p!=-1){

            if(HT[p].lchild == c){
                cd->bit[cd->start] = 0;
            }else{
                cd->bit[cd->start] = 1;
            }
            cd->start--;
            c = p;
            p = HT[c].parent;

        }
        for(j = cd->start+1; j < leght; j++){
            HC[i].bit[j] = cd->bit[j];

        }
 
        
        HC[i].start = cd->start;
        
        free(cd);
    }
}			
void PrintHuffcode(Hcode* HC,int leght){ //输出每个叶子结点的哈夫曼编码

	int i,j;
	printf("\n每个叶子结点的哈夫曼编码为:\n");
	for(i = 0;i < leght;i++){	
        for(j = HC[i].start+1; j < leght; j++){
			printf("%d",HC[i].bit[j]);
        }
        printf("------------>>>%d",i);
        printf("\n");
	}

}	

void Decode(Htree* HT,Hcode* HC,int lenght,char* mch){//译码
    printf("original:");
    int index;
    int i;
    int j = 0;
    index = 2*lenght-2;
    while(mch[j]!='\0'){
        if(mch[j] == '0'){
            index = HT[index].lchild;
        }else{
            index = HT[index].rchild;
        }
        if(HT[index].lchild == -1 && HT[index].rchild == -1){          
                printf("%c",HC[index].ch);
                index = 2*lenght-2;          
        }
        j++;
    }
    printf("\n");

}

int main(void){
    int w[3] = {1,1,2};
    char ch[3] = {'m','n','c'};
    char mch[MAXVALUE] = {"011100111001110011100111001110"};


    int leght = 3;
    int i;
    Htree * HT = InitHtree(w,leght);
    Hcode * HC = InitHcode(leght,ch);

    CreateHuffTree(HT,leght);

    CreateHuffCode(HC,HT,leght);

    PrintHuffTree(HT,HC,2*leght-2,leght);
    PrintHuffcode(HC,leght);
    Decode(HT,HC,leght,mch);



    return 0;
}

我也是熬夜写过的,头都秃了

我是菜鸟一个,大佬们轻喷

举报

相关推荐

0 条评论