主题:[原创]我的一个产生哈夫曼编/译码演示系统的C程序
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define M 50
int n,m;
struct node /*tree struct*/
{
int weight;
int parent;
int lchild,rchild;
char c;
int num;
};
struct node *ht;
typedef char * *hfmcode;
hfmcode HC;
char wd[M];
FILE *fp1,*fp2,*fp3,*h,*fp4,*fp5;
void Initialization()
{
int i=0,j=0,k=0,x=0,y=0,b=0,tm=0;
int p=0,r=0,l=0,w=0;
int tmp;
char ch;
ht=(struct node *)malloc((m+1)*sizeof(struct node));
for(i=1;i<=n;i++)
{
puts("input a char:");
scanf("%c",&ht[i].c);
wd[i]=ht[i].c;
while(getchar()!='\n')
continue;
puts("input the weight of this char:");
scanf("%d",&ht[i].weight);
while(getchar()!='\n')
continue;
ht[i].parent=0;
ht[i].rchild=0;
ht[i].lchild=0;
ht[i].num=i;
}
for(i=n+1;i<=m;i++) /*adding branch */
{
ht[i].parent=0;
ht[i].num=i;
ht[i].weight=0;
ht[i].lchild=0;
ht[i].rchild=0;
ht[i].c='$';
}
for(i=1;i<n;i++) /*sort */
{
k=i;
for(j=i+1;j<n+1;j++)
if(ht[j].weight<ht[k].weight) k=j;
p=ht[k].parent;
w=ht[k].weight;
r=ht[k].rchild;
l=ht[k].lchild;
tmp=ht[k].num;
ch=ht[k].c;
ht[k].parent=ht[i].parent;
ht[k].weight=ht[i].weight;
ht[k].rchild=ht[i].rchild;
ht[k].lchild=ht[i].lchild;
ht[k].num=ht[i].num;
ht[k].c=ht[i].c;
ht[i].parent=p;
ht[i].weight=w;
ht[i].rchild=r;
ht[i].lchild=l;
ht[i].num=tmp;
ht[i].c=ch;
}
y=n+1;
x=1; b=2;
for(i=n+1;i<=m;i++,x+=2,b+=2,y++)
{
ht[x].parent=i; ht[b].parent=i;
ht[i].lchild=ht[x].num; ht[i].rchild=ht[b].num;
ht[i].weight=ht[x].weight+ht[b].weight;
for(tm=1;tm<y;tm++) /*sort */
{
k=tm;
for(j=tm+1;j<y+1;j++)
if(ht[j].weight<ht[k].weight) k=j;
p=ht[k].parent; w=ht[k].weight; r=ht[k].rchild; l=ht[k].lchild;
tmp=ht[k].num; ch=ht[k].c;
ht[k].parent=ht[tm].parent; ht[k].weight=ht[tm].weight; ht[k].rchild=ht[tm].rchild;
ht[k].lchild=ht[tm].lchild; ht[k].num=ht[tm].num;
ht[k].c=ht[tm].c;
ht[tm].parent=p; ht[tm].weight=w; ht[tm].rchild=r; ht[tm].lchild=l;
ht[tm].num=tmp; ht[tm].c=ch;
}
}
for(i=1;i<m;i++) /* the last time repair */
{
k=i;
for(j=i+1;j<m+1;j++)
if(ht[j].num<ht[k].num) k=j;
p=ht[k].parent;
w=ht[k].weight;
r=ht[k].rchild;
l=ht[k].lchild;
tmp=ht[k].num;
ch=ht[k].c;
ht[k].parent=ht[i].parent;
ht[k].weight=ht[i].weight;
ht[k].rchild=ht[i].rchild;
ht[k].lchild=ht[i].lchild;
ht[k].num=ht[i].num;
ht[k].c=ht[i].c;
ht[i].parent=p;
ht[i].weight=w;
ht[i].rchild=r;
ht[i].lchild=l;
ht[i].num=tmp;
ht[i].c=ch;
}
printf("the lasted hffmantree is :\n");
printf(" number zifu weight parent lchild rchild\n");
for(i=1;i<=m;i++)
printf("%4d %13c %13d %13d %13d %13d\n",ht[i].num,ht[i].c,ht[i].weight,ht[i].parent,ht[i].lchild,ht[i].rchild);
if((h=fopen("hfmTree","wb"))==NULL)
{ printf("cannot open file\n");
exit(0);
}
for(i=1;i<=m;i++)
fprintf(h,"%4d %13c %13d %13d %13d %13d\r\n",ht[i].num,ht[i].c,ht[i].weight,ht[i].parent,ht[i].lchild,ht[i].rchild);
fclose(h);
}
void Encode()
{ int i,mm,c,f,start;
char wr,*cd,*str,ch;
if((h=fopen("hfmTree","rb"))==NULL)
{ printf("cannot open file\n");
exit(0);
}
for(i=1;i<=m;i++)
fscanf(h,"%4d %13c %13d %13d %13d %13d\n",ht[i].num,ht[i].c,ht[i].weight,ht[i].parent,ht[i].lchild,ht[i].rchild);
fclose(h);
HC=(hfmcode)malloc((n+1)*sizeof(char *));
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));
strcpy(HC[i],&cd[start]);
}
free(cd);
for(i=1;i<=n;i++)
printf("%c----%s\n",wd[i],HC[i]);
puts("IF input the file tobetran select A or a, ELSE read from disk! ARE YOU SURE?");
printf("PLEASE INPUT:");
scanf("%c",&wr);getchar();
if(wr=='a'||wr=='A')
{ if((fp1=fopen("ToBeTran","w"))==NULL)
{ printf("cannot open file\n");
exit(0);
}
printf("Please input the tobetran:\n");
ch=getchar();
while(ch!='#')
{ fputc(ch,fp1);
putchar(ch);
ch=getchar();
}
fclose(fp1);
}
printf("\n");
getchar();
if((fp1=fopen("ToBeTran","r"))==NULL)
{ printf("cannot open file\n");
exit(0);
}
if((fp2=fopen("CodeFile","w"))==NULL)
{ printf("cannot open file\n");
exit(0);
}
while(!feof(fp1))
{ ch=fgetc(fp1);
for(i=1;i<=n;i++) if(wd[i]==ch) for(mm=0;HC[i][mm]!='\0';mm++) fputc(HC[i][mm],fp2);
}
fclose(fp1);
fclose(fp2);
}
void Decode()
{ int i,c,f=m;
char ch;
if((h=fopen("hfmTree","rb"))==NULL)
{ printf("cannot open file\n");
exit(0);
}
for(i=1;i<=m;i++)
fscanf(h,"%4d %13c %13d %13d %13d %13d\n",ht[i].num,ht[i].c,ht[i].weight,ht[i].parent,ht[i].lchild,ht[i].rchild);
fclose(h);
if((fp2=fopen("CodeFile","r"))==NULL)
{ printf("cannot open file\n");
exit(0);
}
if((fp3=fopen("TextFile","w"))==NULL)
{ printf("cannot open file\n");
exit(0);
}
while(!feof(fp2))
{ ch=fgetc(fp2); printf("%c",ch);
if(ch=='0') f=ht[f].lchild;
if(ch=='1') f=ht[f].rchild;
if(!ht[f].lchild&&!ht[f].rchild) { fputc(wd[f],fp3); f=m; }
}
fclose(fp2);
fclose(fp3);
printf("\n");
}
void Printcode()
{ int i=0;
char ch;
if((fp2=fopen("CodeFile","r"))==NULL)
{ printf("cannot open file\n");
exit(0);
}
if((fp4=fopen("CodePrin","w"))==NULL)
{ printf("cannot open file\n");
exit(0);
}
while(!feof(fp2)) { if(i==50) { printf("\n"); i=0; } ch=fgetc(fp2); fputc(ch,fp4); printf("%c",ch); i++; }
printf("\n");
fclose(fp2);
fclose(fp4);
}
void Printtree()
{ int i,k,top,b,p;
int *level,*stack;
printf("THE HUFFMANTREE IS :\n");
level=(int *)malloc(n*sizeof(int));
stack=(int *)malloc(n*sizeof(int));
if((h=fopen("hfmTree","rb"))==NULL)
{ printf("cannot open file\n");
exit(0); }
for(i=1;i<=m;i++)
fscanf(h,"%4d %13c %13d %13d %13d %13d\n",ht[i].num,ht[i].c,ht[i].weight,ht[i].parent,ht[i].lchild,ht[i].rchild);
fclose(h);
b=m;
if(b!=0)
{ top=1; stack[top]=b; level[top]=3;
while(top>0)
{ p=stack[top]; k=level[top]; for(i=1;i<=k;i++) printf(" ");
printf("%d\n",ht[p].weight);
top--;
if(ht[p].rchild!=0)
{ top++; stack[top]=ht[p].rchild; level[top]=k+3; }
if(ht[p].lchild!=0)
{ top++; stack[top]=ht[p].lchild; level[top]=k+3; }
}
}
if((fp5=fopen("TreePrint","w"))==NULL)
{ printf("cannot open file\n");
exit(0); }
for(i=1;i<=m;i++)
fprintf(fp5,"%4d %13c %13d %13d %13d %13d\r\n",ht[i].num,ht[i].c,ht[i].weight,ht[i].parent,ht[i].lchild,ht[i].rchild);
fclose(fp5);
}
void main()
{ char en;
printf("********************huffmantree encode/decode display ststem*******************\n");
puts("i/I---Initialization d/D---decode q/Q---end");
puts("t/T---print hfmtree e/E---encode p/P---print file's code");
puts("********************huffmantree encode/decode display ststem********************");
puts("please select a menu number:");
scanf("%c",&en);getchar();
for(;!(en=='q'||en=='Q');)
{
if(en=='i'){puts("input the number of the total char n:");scanf("%d",&n);m=2*n-1;
while(getchar()!='\n') continue; Initialization();}
if((en=='e')||(en=='E')) Encode();
if((en=='d')||(en=='D')) Decode();
if((en=='p')||(en=='P')) Printcode();
if((en=='t')||(en=='T')) Printtree();
puts("*******************huffmantree encode/decode display ststem*******************");
puts("i/I---Initialization d/D---decode q/Q---end");
puts("t/T---print hfmtree e/E---encode p/P---print file's code");
puts("*******************huffmantree encode/decode display ststem*******************");
puts("please select a menu number:");
scanf("%c",&en);
while(getchar()!='\n') continue;
}
}