哈夫曼树译码的判断条件问题
本来的想法是如果输入的哈夫曼编码和上面储存的完全匹配则输出对应的原字符,但是现在弄不出来,不知道是什么原因,希望有大神来给我看看问题在哪程序代码:
#include<stdio.h> #include<stdlib.h> #include<string.h> #define MAXBIT 10//每个字符编码的最大长度 #define MAXVALUE 1000//哈夫曼树中叶子结点的最大权值 #define MAXSIZE 26//电文中出现的字符种类的最大值 typedef struct HNode//定义哈夫曼树的结点结构 { int weight; int parent,lchild,rchild; }HNode,*HTree; typedef char **HCode;//哈夫曼编码 //统计电文中的字符种类及每种字符出现的次数 int Count(char *s,int cnt[],char str[]) { //*s指向电文字符串,cnt存储电文中字符出现的次数,str存储电文中出现的字符 char *p; int i,j,k; int temp[26];//temp是临时数组,用于统计每个字符出现的次数 for(i=0;i<26;i++) temp[i]=0; for(p=s;*p!='\0';p++)//统计各种字符出现的次数 if(*p>='A'&&*p<='Z') { k=(*p)-65; temp[k]++; } for(i=0,j=0;i<26;i++)//统计电文中出现的字符 if(temp[i]!=0) { str[j]=i+65;//将出现的字符存入字符数组 cnt[j]=temp[i];//相应字符出现的次数作为该字符的权值存储到cn j++; } str[j]='\0'; return j;//返回电文中字符的种类,即哈夫曼树种叶子结点个数 } //构造哈夫曼树并生成叶子结点的前缀编码 void HuffmanCoding(HTree *HT,HCode *HC,int *w,int n) { //w存储n个字符的权值,构造哈夫曼树HT,并求出n个字符的哈夫曼编码HC int m;//哈夫曼树中结点的个数 int m1,m2,x1,x2;//m1、m2存储两个最小权值,x1、x2存储对应的下标 int i,j,start; char *cd; int c,f; HNode *p; if(n<=1) return; //哈夫曼树的构造 m=2*n-1; *HT=(HNode *)malloc(m*sizeof(HNode)); for(p=*HT,i=0;i<n;++i,++p,++w)//初始化叶子结点信息 { p->weight=*w; p->lchild=-1; p->rchild=-1; p->parent=-1; } for(;i<m;++i,++p)//初始化分支结点信息 { p->weight=0; p->lchild=-1; p->rchild=-1; p->parent=-1; } for(i=n;i<m;++i)//构造哈夫曼树 { m1=m2=MAXVALUE; x1=x2=0; for(j=0;j<i;++j)//寻找parent为-1且权值最小的两棵子树 { if((*HT)[j].parent==-1&&(*HT)[j].weight<m1) { m2=m1; x2=x1; m1=(*HT)[j].weight; x1=j; } else if((*HT)[j].parent==-1&&(*HT)[j].weight<m2) { m2=(*HT)[j].weight; x2=j; } } //合并成一棵新的子树 (*HT)[x1].parent=i; (*HT)[x2].parent=i; (*HT)[i].lchild=x1; (*HT)[i].rchild=x2; (*HT)[i].weight=m1+m2; } *HC=(HCode)malloc(n*sizeof(char *)); cd=(char *)malloc(n*sizeof(char)); cd[n-1]='\0'; for(i=0;i<n;++i) { start=n-1; for(c=i,f=(*HT)[i].parent; f!=-1;c=f,f=(*HT)[f].parent) if((*HT)[f].lchild==c) cd[--start]='0'; else cd[--start]='1'; (*HC)[i]=(char *)malloc((n-start)*sizeof(char)); //为第i个字符编码分配空间 strcpy((*HC)[i],&cd[start]);//从cd复制编码串到HC[i] } free(cd); } void HuffmanDecoding(HCode HC,HTree *HT,char str[],int n) { int i,j=0; char b[MAXSIZE]; int m=2*n-1; i=m-1; //从根结点开始往下搜索 printf("输入发送的编码(以'#'为结束标志):"); gets(b); printf("译码后的字符为"); while(b[j]!='#') { if(b[j]=='0') i=(*HT)[i].lchild; //走向左孩子 else i=(*HT)[i].rchild; //走向右孩子 if(strcmp(HC[j],b)==0) { printf("%c",str[i]); i=m-1;//回到根结点 } j++; } } void Print(HCode HC,char str[],int cn[],int n)//输出电文中每个字符出现的次数及其前缀编码 { int i; for(i=0;i<n;i++) { printf("%c出现%d次,编码是:",str[i],cn[i]); puts(HC[i]); putchar('\n'); } return; } main() { char st[254],*s,str[26]; int cn[26]; int num; HNode *HT; HCode HC; printf("输入需要编码的大写英文字母字符串:\n"); gets(st); num=Count(st,cn,str); HuffmanCoding(&HT,&HC,cn,num); Print(HC,str,cn,num); HuffmanDecoding(HC,&HT,str,num); }