#include
#include
#include
#include
#include
#include
#define N 256
typedef struct ascllarray
{
char ascll;//字符对应的Ascll码值
int num;//出现次数即权值
}ascllarray;
ascllarray array[N];
typedef struct huffmantree
{
char data;
int weight;
int parent;
int lchild;
int rchild;
}huffmantree;
huffmantree htree[2*N];
typedef struct huffmancode
{
char ascll;
char code[N];
}huffmancode;
huffmancode hcode[N];
int huffmanleaf=0;//定义为全局变量
FILE *fp;
//函数申明
void select(huffmantree htree[],int m,int *a);
void creatweightfile();
void creathuffmantree();
void creathuffmancode();
void codingsourcefile();
void menu();
void creatweightfile()/*将源文件中的字符和出现次数统计出来写入weightarray.txt文件中*/
{
int i;
char ch;
fp=fopen("sourcefile1.txt","rt");
if(fp==NULL)
{
printf("can not open\n");
printf("press any button:");
getch();
system("cls");
menu();
}
ch=fgetc(fp);
while(EOF!=ch)/*扫描文件,统计字符出现次数,放在array数组中*/
{
i=ch;
array[i].ascll=ch;
array[i].num++;
ch=fgetc(fp);
}
fclose(fp);
fp=fopen("weightarray.txt","wt");/*以写入方式打开,将数组中字符次数不为0的项写入*/
if(fp==NULL)
{
printf("can not open\n");
exit(1);
}
for(i=1;i<=N;i++)
{
if(array[i].num!=0)
{
fprintf(fp,"%c%d",array[i].ascll,array[i].num);
huffmanleaf++;
}
}
fclose(fp);
}
/*void seeweight()
{
int i;
fp=fopen("weightarray.txt","rt");
if(fp==NULL)
{
printf("can not open\n");
printf("press any button:");
getch();
system("cls");
menu();
}
for(i=1;i<=huffmanleaf;i++)
{
fscanf(fp,"%c%d",&array[i].ascll,&array[i].num);
}
for(i=1;i<=huffmanleaf;i++)
{
if(array[i].ascll==' ')
{
printf("空格%d ",array[i].num);
}
else if(array[i].ascll=='\n')
{
printf("换行%d ",array[i].num);
}
else
{
printf("%c %d ",array[i].ascll,array[i].num);
}
if(i%4==0)
{
printf("\n");
}
}
printf("\n");
printf("press any button:");
getch();
system("cls");
menu();
}*/
void creathuffmantree()/*创建哈夫曼树*/
{
int i;
int s1=0,s2=0;
fp=fopen("weightarray.txt","rt");
if(fp==NULL)
{
printf("can not open\n");
printf("press any button:");
getch();
system("cls");
menu();
}
for(i=1;i<=huffmanleaf;i++)
{
fscanf(fp,"%c%d",&htree[i].data,&htree[i].weight);
}
for( i=huffmanleaf+1; i<2*huffmanleaf; i++ )
{
select(htree,i-1,&s1);
htree[s1].parent=i;
select(htree,i-1,&s2);
htree[s2].parent=i;
htree[i].weight=htree[s1].weight+htree[s2].weight;
htree[i].lchild=s1;
htree[i].rchild=s2;
}
printf("finished\n");
printf("press any button:");
getch();
system("cls");
menu();
}
void select(huffmantree htree[],int m,int *a)
{
int i,min;
min=20000;
for( i=1; i<=m; i++ )
{
if( htree[i].weig
ht < min && htree[i].parent == 0 )
{
* a = i;
min = htree[i].weight;
}
}
}
void creathuffmancode()//创建哈夫曼编码,按照字符的ascll码值对应序号顺序存储在hcode[]结构体数组
{
int i,j,c,p,k;
char *cd;
j=huffmanleaf;
cd=(char *)malloc((j+1)*sizeof(char));
cd[j] = '\0';
for(i=1;i<=huffmanleaf;i++)
{
c=i;
k=htree[i].data;
j=huffmanleaf;
p=htree[i].parent;
while(p!=0)
{
j-=1;
if(htree[p].lchild==c)
{
cd[j]='0';
}
else if(htree[p].rchild==c)
{
cd[j]='1';
}
c=p;
p=htree[p].parent;
}
strcpy(hcode[k].code,&cd[j]);
hcode[k].ascll=htree[i].data;
}
printf("叶子个数:%d\n",huffmanleaf);
for(i=1;i
if(hcode[i].ascll!='-')
{
printf("%c %s\n",hcode[i].ascll,hcode[i].code);
}
}
printf("press any button");
getch();
system("cls");
menu();
}
/*void savehuffmancode()
{
FILE *fp;
int i;
fp=fopen("huffmancode.txt","wt");
if(fp==NULL)
{
printf("can not open\n");
printf("press any button:");
getch();
system("cls");
menu();
}
for(i=1;i<=huffmanleaf;i++)
{
fwrite(hcode,sizeof(struct huffmancode),1,fp);
}
fclose(fp);
printf("huffmancode be created and saved\n");
}
void seehuffmancode()
{
int i;
fp=fopen("huffmancode.txt","rt");
if(fp==NULL)
{
printf("can not open\n");
printf("press any button:");
getch();
system("cls");
menu();
}
fread(hcode,sizeof(struct huffmancode),huffmanleaf,fp);
for(i=1;i<=huffmanleaf;i++)
{
if(hcode[i].ascll!='-')
{
if(hcode[i].ascll==' ')
{
printf("空格%s\n",hcode[i].code);
}
else if(hcode[i].ascll=='\n')
{
printf("换行%s\n",hcode[i].code);
}
else
{
printf("%c %s\n",hcode[i].ascll,hcode[i].code);
}
}
}
printf("press any button:");
getch();
system("cls");
menu();
}
*/
void codingsourcefile()//文件压缩
{
int i;
FILE *fp1;
char ch;
fp=fopen("codefile.txt","wt");
fp1=fopen("sourcefile1.txt","rt");
if(fp==NULL||fp1==NULL)
{
printf("can not open huffmancodefile\n");
printf("press any button:");
getch();
system("cls");
menu();
}
ch=fgetc(fp1);
i=ch;
while(ch!=EOF)
{
fputs(hcode[i].code,fp);
ch=fgetc(fp1);
i=ch;
}
fclose(fp);
fclose(fp1);
printf("coding finished\n");
printf("press any button");
getch();
system("cls");
menu();
}
void menu()
{
char c;
printf("---------------哈夫曼编译码器---------------\n\n\n");
printf("choose:");
printf(" 1.创建哈夫曼树 \n");
printf(" 2.创建哈夫曼编码 \n");
printf(" 3.编码源文件 \n");
printf(" 4.退出 \n");
c=getchar();
switch(c)
{
case '1':
{
creathuffmantree();
break;
}
case '2':
{
creathuffmancode();
break;
}
case '3':
{
codingsourcefile();
break;
}
case '4':
{
exit(1);
break;
}
default:
{
system("cls");
menu();
break;
}
}
}
void main()
{
int i;
for(i=1;i
hcode[i].ascll='-';
}
creatweightfile();//准备工作,并且计算出叶子个数
menu();
}