#include<stdlib.h>
#define MAX 27
typedef struct
{
char data;
long weight;
long parent;
long left;
long right;
}huffnode;
typedef struct
{
char cd[MAX];
int start;
}huffcode;
void save(huffnode huff1[2*MAX])//**************************保存哈樹****************************
{
FILE *p;
int i;
p=fopen("hfmTree.txt","wb");
for(i=0;i<2*MAX;i++)
fwrite(&huff1[i],sizeof(huffnode),1,p);
fclose(p);
}
void read(huffnode huff2[2*MAX])//**********************************讀哈樹***************************************
{
FILE *p;
int i;
p=fopen("hfmTree.txt","rb");
for(i=0;i<2*MAX;i++)
{
fread(&huff2[i],sizeof(huffnode),1,p);
//printf("%10c%10d%10d%10d%10d",huff2[i].data,huff2[i].left,huff2[i].parent,huff2[i].right,huff2[i].weight);
}
fclose(p);
}
void inputs()//*************************編碼字符串的輸入************************************
{
printf("請輸入要編碼的字符串,以#結束:");
getchar();
FILE *fp;
char ch;
fp=fopen("ToBeTran.txt","w");
//ch=getchar();
ch=getchar();
while(ch!='#')
{
fputc(ch,fp);
ch=getchar();
}
fclose(fp);
}
void outputs(char a[1000])//*******************************譯嗎碼字符串讀出***********************
{
int i=0;
FILE *fp;
char ch;
fp=fopen("ToBeTran.txt","r");
ch=fgetc(fp);
while(ch!=EOF)
{
//printf("%c",ch);
a[i]=ch;
i++;
ch=fgetc(fp);
}
fclose(fp);
}
void disp()//******************************打印樹
{ huffnode huff[2*MAX];
read(huff);
int top1;
huffnode stack[100],p;
int level[100],top,n,i;
if (huff!=NULL)
{
printf("該二叉樹表示法:/n");
top=1;
stack[top]=huff[2*MAX-1];
level[top]=3;
while(top>0)
{
p=stack[top];
n=level[top];
for(i=1;i<=n;i++)
printf(" ");
printf("%d/n",p.weight);
top--;
if (p.right!=NULL)
{
top++;
top1=p.right;
stack[top]=huff[top1];
level[top]=n+3;
}
if (p.left!=NULL)
{
top++;
top1=p.left;
stack[top]=huff[top1];
level[top]=n+3;
}
}
}
printf("/n");
}
void outputsb(char a[1000])//*******************************編碼字符串讀出***********************
{
int i=0;
FILE *fp;
char ch;
fp=fopen("CodeFile.txt","r");
ch=fgetc(fp);
while(ch!=EOF)
{
//printf("%c",ch);
a[i]=ch;
i++;
ch=fgetc(fp);
}
fclose(fp);
}
void code()//編碼***************************************************************
{
FILE *p;
p=fopen("CodeFile.txt","w");
fclose(p);
huffnode ht[2*MAX];
huffcode d,hcd[MAX];
char a[100];
int j,f,c,k,i;
read(ht);
inputs();
outputs(a);
for(j=0;j<sizeof(a);j++)
{
for(i=1;i<=MAX;i++)
{if(a[j]==ht[i].data)
{d.start=MAX+1;
c=i;
f=ht[i].parent;
while(f!=0)
{
if(ht[f].left==c)
d.cd[--d.start]='0';
else
d.cd[--d.start]='1';
c=f;
f=ht[f].parent;
}
hcd[i]=d;
//printf("輸出哈夫曼編碼:/n");
//for(i=1;i<=MAX;i++)
// printf("%c:",ht[i].data);
for(k=hcd[i].start;k<=MAX;k++)
{FILE *fp;
char ch;
ch=hcd[i].cd[k];
fp=fopen("CodeFile.txt","a");
fputc(ch,fp);
fclose(fp);
}
//printf("/n");
}
}
}
}
void decode()//譯碼**********************************************************
{
FILE *p;
p=fopen("TextFile.txt","w");
fclose(p);
int k;
char a[100];
for(k=0;k<100;k++)
a[k]='2';
huffnode huff[2*MAX];
read(huff);
outputsb(a);
int i,m,j;
i=0;
m=2*MAX-1;
j=m;
//while(a[i]!=EOF)
//{
//if (b!=EOF)
while(a[i]!='2')
{//b=int(a[i]);
if(a[i]=='0')
j=huff[j].left;
else
j=huff[j].right;
if(huff[j].right==0)
{
printf("%c",huff[j].data);
j=m;
FILE *fp;
char ch;
ch=huff[j].data;
fp=fopen("TextFile.txt","a");
fputc(ch,fp);
fclose(fp);
}
i++;
}
printf("/n");
}
void print()//打印代碼******************************************************
{
int i=0;
FILE *fp;
char ch;
fp=fopen("CodeFile.txt","r");
ch=fgetc(fp);
while(ch!=EOF)
{
char a[100];
printf("%c",ch);
a[i]=ch;
i++;
ch=fgetc(fp);
if(i%50==0)
printf("/n");
}
fclose(fp);
printf("/n");
}
void main()
{
int x;
puts("*******************哈夫曼編/譯碼器演示******************************");
while(1){
start:
puts("1. 初始化 2. 編碼 3. 譯碼 4.打印代碼 5. 打印樹 6.退出");
while(scanf("%d",&x)!=1)
{
while(getchar()!='/n')
continue;
puts("輸入錯誤!");
puts("請重新輸入!");
puts("1. 初始化 2. 編碼 3. 譯碼 4.打印代碼 5. 打印樹 6.退出");
}
switch (x)
{
case 1:
goto settree;
break;
case 2:
code();
break;
case 3:
decode();
break;
case 4:
print();
break;
case 5:
disp();
break;
case 6:
exit(0);
default:
puts("輸入錯誤!");
puts("請重新輸入!");
goto start;
}
}
settree:
huffnode ht[2*MAX],huff[2*MAX];
huffcode hcd[MAX],d;
int i,k,f,l,r,n,c,m1,m2;
printf("元素個數:");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
getchar();
printf("第%d個元素=>/n/t結點值:",i);
scanf("%c",&ht[i].data);
printf("/t權重:");
scanf("%d",&ht[i].weight);
}
//***********************************樹的錄入******************************************
for(i=1;i<=2*n-1;i++)
ht[i].parent=ht[i].left=ht[i].right=0;
for(i=n+1;i<=2*n-1;i++)
{
m1=m2=32767;
l=r=0;
for(k=1;k<=i-1;k++)
if(ht[k].parent==0)
if(ht[k].weight<m1)
{
m2=m1;
r=l;
m1=ht[k].weight;
l=k;
}
else if(ht[k].weight<m2)
{
m2=ht[k].weight;
r=k;
}
ht[l].parent=i;
ht[r].parent=i;
ht[i].weight=ht[l].weight+ht[r].weight;
ht[i].left=l;
ht[i].right=r;
}
for(i=1;i<=n;i++)
//printf("%10c%10d%10d%10d%10d",ht[i].data,ht[i].left,ht[i].parent,ht[i].right,ht[i].weight);
for(i=1;i<=n;i++)
{
d.start=n+1;
c=i;
f=ht[i].parent;
while(f!=0)
{
if(ht[f].left==c)
d.cd[--d.start]='0';
else
d.cd[--d.start]='1';
c=f;
f=ht[f].parent;
}
hcd[i]=d;
}
printf("輸出哈夫曼編碼:/n");
for(i=1;i<=n;i++)
{
printf("%c:",ht[i].data);
for(k=hcd[i].start;k<=n;k++)
printf("%c",hcd[i].cd[k]);
printf("/n");
}
save(ht);
//read(huff);
//code();
//decode();
goto start;
}