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;
}