#include"stdio.h"
#include"malloc.h"
#include"string.h"
#define M 27
#define MZ 1000
typedef struct
{
unsigned int w;
unsigned int parent,lchild,rchild;
char info;
}Huf,*HufTree;
typedef struct
{
HufTree HT;
char ** Huffcode;
}store;
typedef char ** Huffcode;
void init(char Noc[],int wc[])
{
for(int i=0;i<M;i++)
{
printf("输入字符:");
Noc[i]=getchar();
getchar();
printf("输入权直:");
scanf("%d",wc+i);
getchar();
}
}
void select(HufTree HT,int n,int *s1,int *s2)
{
int m1,m2;
m1=3000;
m2=3000;
int i;
for(i=1;i<=n;i++)
{
if(HT[i].parent ==0)
{ if(HT[i].w<m1) { m1=HT[i].w;*s1=i;}
else
if(HT[i].w<m2){m2=HT[i].w;*s2=i;}
}
}
}
store Huffmancode(HufTree HT,Huffcode HC,int *w,int n,char code[])
{
int i=0,s1,s2;
char *cd;
s1=2;
s2=1;
Huf *p;
int m;
//if(n<=1) return ;
m=2*n-1;
store st;
HT=(Huf *)malloc((m+1)*sizeof(Huf));
HT[0].lchild=0;
HT[0].parent=0;
HT[0].rchild=0;
HT[0].w=0;
HT[0].info=code[0];
for(p=HT+1,i=1;i<=n;++i,++p,++w)
{
p->w=*w;
p->lchild =0;
p->parent=0;
p->rchild=0;
p->info=code[i-1];
}
for(;i<=m;++i,++p)
{
p->lchild=0;
p->parent=0;
p->rchild=0;
p->w=0;
HT[i].info='*';
}
for(i=n+1;i<=m;++i)
{
select(HT,i-1,&s1,&s2);
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].w=HT[s1].w+HT[s2].w;
}
int start,c,f;
HC=(Huffcode)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);
//printf("%c/n",HT[i].info);
}
free(cd);
st.HT=HT;
st.Huffcode=HC;
return st;
}
int fcode(char Noc[],store *st)
{
char code[MZ];
int n=0;
int low=0,high=26;
int mid,i=0;
printf("===========请输入你要编码的数据(一次最多可以编码1000个字符)============/n");
printf("| 注意以*字符为结束标志 |/n");
printf("=======================================================================/n");
//scanf("%s",code);
getchar();
gets(code);
while(i<1000)
{
if(code[i]=='*') return 0;
low=0;
high=26;
while(low<=high)
{
mid=(low+high)/2;
if(Noc[mid]==code[i]){ printf("%s",st->Huffcode[mid+1]);break;}
else
{
if(Noc[mid]>code[i]) high=mid-1;
else low=mid+1;
}
}
i++;
}
printf("/n");
return 0;
}
int uncode(store *st,int m)
{
char code[1000];
int n=0,i=0;
n=m;
printf("==========================输入你要译码的数据===================/n");
printf("| 注意以*字符为结束标志 |/n");
printf("===============================================================/n");
scanf("%s",code);
while(true)
{
if(code[i]=='*')break;
if(code[i]=='0')
n=st->HT[n].lchild;
else
n=st->HT[n].rchild;
if(st->HT[n].info!='*')
{
printf("%c",st->HT[n].info);
n=m;
}
i++;
}
printf("/n");
return 0;
}
void print(store *st,char Noc[])
{
for(int i=0;i<M;i++)
{
printf("==================================/n");
printf("==%c=的编码为:",Noc[i]);
printf("%s/n",st->Huffcode[i+1]);
}
printf("==================================/n");
}
int main()
{
Huf HT;
char *HC;
store st;
char Nocode[M]={' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
int WC[M]={186,64,13,22,32,103,21,15,47,57,1,5,32,20,57,63,15,1,48,51,80,23,8,18,1,16,1};
int falg;
st=Huffmancode(&HT,&HC,WC,M,Nocode);
while(falg!=4)
{
printf(" ====================功能选项==================/n");
printf(" | =编码是1= =译码是2= =编码表3= =退出请选4= |/n");
printf(" ==============================================/n");
printf(" 输入值:");
scanf("%d",&falg);
switch(falg)
{
case 1:fcode(Nocode,&st);break;
case 2:uncode(&st,2*M-1);break;
case 3:print(&st,Nocode);break;
case 4:printf("谢谢你的使用!/n");break;
}
}
return 0;
}