Huffman编码
main.h
#ifndef main_h #define main_h typedef struct HTNode { int weight; int lchild,rchild,parent; }HTNode; typedef struct HCNode { char ch; char bits[27]; int len; }HCNode; #endif
#include<stdio.h> #include<stdlib.h> #include<string.h> #include"main.h" int ScanString(char str[],char s[],int ct[]) { int num=0,i; int temp[27]; for(i=1;i<27;i++) temp[i]=0; for(i=0;str[i];i++) if(str[i]>=‘a‘&&str[i]<=‘z‘) temp[str[i]-‘a‘+1]++; for(i=1;i<27;i++) if(temp[i]) { num++; s[num]=‘a‘+i-1; ct[num]=temp[i]; } return num; } void Select(HTNode *HT,int k,int *s1,int *s2) { int m1=32767,m2=32767; int i; for(i=1;i<=k;i++) { if(HT[i].weight<m1&&HT[i].parent==0) { m1=HT[i].weight; *s1=i; } } for(i=1;i<=k;i++) { if(HT[i].weight<m2&&HT[i].parent==0&&*s1!=i) { m2=HT[i].weight; *s2=i; } } } void CHuffTree(HTNode *HT,char s[],int ct[],int num) { int i,s1,s2; for(i=1;i<num*2;i++) HT[i].lchild=HT[i].rchild=HT[i].parent=HT[i].weight=0; for(i=1;i<=num;i++) HT[i].weight=ct[i]; for(i=num+1;i<2*num;i++) { Select(HT,i-1,&s1,&s2); HT[s1].parent=i; HT[s2].parent=i; HT[i].lchild=s1; HT[i].lchild=s2; HT[i].weight=HT[s1].weight+HT[s2].weight; } } void GetCode(HTNode *HT,HCNode *HC,char s[],int num) { char cd[27]; int start; int p,c,i; cd[27]=‘\0‘; for(i=1;i<=num;i++) HC[i].ch=s[i]; for(i=1;i<=num;i++) { start=27; c=i; while((p=HT[c].parent)>0) { if(HT[p].lchild==c) cd[--start]=‘0‘; else cd[--start]=‘1‘; c=p; } strcpy(HC[i].bits,&cd[start]); HC[i].len=27-start; } } void Coding(HCNode *HC,char str[],int num) { int i,j; FILE *fp; fp=fopen("codefile.dat","w"); if(fp==NULL) { printf("Can not open the file!\n"); return ; } while(*str) { for(i=1;i<=num;i++) { if(*str==HC[i].ch) { for(j=0;j<HC[i].len;j++) fprintf(fp,"%c",HC[i].bits[j]); break; } } str++; } fclose(fp); } void Decoding(HCNode *HC,char code[],int num) { int flag,i,j,k=0; char cd[27]; FILE *fp; fp=fopen("codefile.dat","r"); if(fp==NULL) { printf("Can not open the file!\n"); return ; } while(!feof(fp)) { flag=0; for(i=0;i<=num&&flag==0&&!feof(fp);i++) { cd[i]=‘ ‘; cd[i+1]=‘\0‘; fscanf(fp,"%c",&cd[i]); for(j=1;j<=num;j++) { if(strcmp(cd,HC[j].bits)==0) { code[k++]=HC[j].ch; flag=1; break; } } } } code[k]=‘\0‘; fclose(fp); } int main(int argc,char *argv[]) { HTNode *HT; HCNode *HC; FILE *fp; int num,i,k=0; int ct[27]; char s[27]; char str[200],code[200]; char m[200]; printf("Please input:\n"); scanf("%s",str); num=ScanString(str,s,ct); HT=(HTNode *)malloc(sizeof(HTNode)*num*2); HC=(HCNode *)malloc(sizeof(HCNode)*(num+1)); CHuffTree(HT,s,ct,num); GetCode(HT,HC,s,num); Coding(HC,str,num); Decoding(HC,code,num); printf("Code:\n"); for(i=1;i<=num;i++) printf("%c: %s\n",HC[i].ch,HC[i].bits); fp=fopen("codefile.dat","r"); if(fp==NULL) { printf("Can not open the file!\n"); exit(-1); } printf("After coding:\n"); while(!feof(fp)) { fscanf(fp,"%c",&m[k]); k++; } m[k-1]=‘\0‘; printf("%s\n",m); printf("Decoding:\n"); printf("%s\n",code); return 0; }