首页 > 代码库 > 哈弗曼编码和译码.cpp
哈弗曼编码和译码.cpp
<span style="color:#6600cc;">#include<stdio.h> #include<string.h> #include<stdlib.h> typedef struct{ char a;//记录对应字符 int weight;//权值 int parent,lchild,rchild; }HTNode,*HuffmanTree; typedef char * *HuffmanCode;//动态分配数组存储哈夫曼编码表 void Select(HuffmanTree HT,int m,int *s1)//选择双亲节点为0且权值最小的节点 {int i,j,k,h,a,b; for(a=1;a<=m;a++) if(HT[a].parent==0) break; i=a;k=a; for(;i<=m;i++) if(HT[i].weight<HT[k].weight&&HT[i].parent==0) k=i; *s1=k; } //求哈夫曼编码 void HuffmanCoding(HuffmanTree *HT,HuffmanCode *HC,int *w,char *s,int n) { int m,i,start,s1,s2,c,f; char *cd; HuffmanTree p; if(n<=1) return; m=2*n-1; *HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); for(i=1;i<=n;i++,w++,s++) {(*HT)[i].weight=*w;//叶子节点的权值不变 (*HT)[i].a=*s; (*HT)[i].parent=0,(*HT)[i].lchild=0,(*HT)[i].rchild=0;} for(i=n+1;i<=m;i++) (*HT)[i].parent=0;//parent初始化 for(i=n+1;i<=m;++i){//建哈夫曼树 Select(*HT,i-1,&s1);(*HT)[s1].parent=i; Select(*HT,i-1,&s2);/*选择parent为0且权值最小的两个节 点分别作为s1和s2*/ (*HT)[s2].parent=i; (*HT)[i].lchild=s1;(*HT)[i].rchild=s2;(*HT)[i].a='0'; (*HT)[i].weight=(*HT)[s1].weight+(*HT)[s2].weight; } //从叶子到根逆向求每个字符的哈夫曼编码 (*HC)=(HuffmanCode)malloc((n+1)*sizeof(char *));/*分配n个 字符编码的头指针向量*/ cd=(char *)malloc(n*sizeof(char));//分配求编码的工作区间 cd[n-1]='\0';//编码结束符 for(i=1;i<=n;i++){//逐个字符求哈夫曼编码 start=n-1;//编码结束符位置 for(c=i,f=(*HT)[i].parent;f!=0;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 } } //解码 void HUffmanDising(HuffmanTree HT,int n){ FILE *fp3,*fp4;HuffmanTree p; int c,m;char b; p=HT;m=2*n-1;*p=HT[m]; fp3=fopen("File3.txt","r"); fp4=fopen("File4.txt","w"); if(fp3!=NULL) {fscanf(fp3,"%c",&b);/*读入一个字符,如果为‘0’遍历左子树, 为‘1’遍历右子树,遇到叶子节点输出*/ while(!feof(fp3)){ if(b=='0'){ if((*p).a=='0') c=(*p).lchild,(*p)=HT[c];//指向左孩子 } if(b=='1'){ if((*p).a=='0') c=(*p).rchild,(*p)=HT[c];//指向右孩子 } if((*p).a!='0') fprintf(fp4,"%c",(*p).a),//叶子节点输出 (*p)=HT[m];//指向根结点 if(!feof(fp3)) fscanf(fp3,"%c",&b); } } fclose(fp4);fclose(fp3); } void PrintfBitree(HuffmanTree *HT,HuffmanCode *HC,int n) {int i,j=1,m=n*2-1; printf("序号 字符 权值 双亲 左孩子 右孩子 哈夫曼码\n"); for(i=1;i<=m;i++,j++) {printf(" %02d %c %2d %2d %2d %2d",i,(*HT)[i].a,(*HT)[i].weight,(*HT)[i].parent,(*HT)[i].lchild,(*HT)[i].rchild); if(j<=n) printf(" %s ",(*HC)[j]); printf("\n");} } int main() { int a[258],n,c[100],i,j,k,z;char e;char m[100],b; HuffmanTree HT;HuffmanCode HC; FILE *fp1,*fp2,*fp3,*fp4; for(i=0;i<=256;i++) a[i]=0;//读入一个字符,在数组a中的位置由其ASCII吗决定 for(i=0;i<100;i++) c[i]=0;//记录每一个字符的权值 fp1=fopen("File1.txt","r"); if(fp1!=NULL) { while(!feof(fp1)){ fscanf(fp1,"%c",&e); if(!feof(fp1)) a[(int)e]++;//统计出现次数 } } fclose(fp1); for(i=0,j=0;i<=256;i++) if(a[i]!=0) c[j++]=a[i],m[j-1]=(char)i;//将字符存到数组m中 HuffmanCoding(&HT,&HC,c,m,j); fp1=fopen("File1.txt","r"); fp2=fopen("File2.txt","w"); fp3=fopen("File3.txt","w+"); if(fp1!=NULL)//在文件二语三中输出文件一中内容所对应的哈夫曼吗 { while(!feof(fp1)){ fscanf(fp1,"%c",&e); if(feof(fp1)) break; for(i=0;i<j;i++) if(m[i]==e) break; fprintf(fp2,"%s",HC[i+1]); fprintf(fp3,"%s",HC[i+1]); } } fclose(fp1); fclose(fp2); fclose(fp3); PrintfBitree(&HT,&HC,j);//输出相关信息 HUffmanDising(HT,j);//解码函数 } </span>
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。