/*一级指针要改*/
#include "stdio.h"
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#define MAXVALUE 1000
#define MAXSIZE 29
#define MAXBIT 10
typedef struct hnode
{
int weight,parent,lchild,rchild;
}hnode,*htree;
typedef char *hcode;
void huffmancoding(hnode *ht,hcode **hc,int *w,int n)/*hcode是三级指针*/
{
int m,m1,m2,x1,x2,i,j,start,c,f;/*hc本来应该存字符串,一级指针,所以HC在主函数中应为二级指针,但要传递的是数据*/
char *cd; /*所以应把二级指针的地址给形参,及形参应为三级指针*/
hnode *p; /*同理HT在形参中应作为HNODE的地址,及一级指针*/
if(n<=1) return; /*值传递传的是原值的一个拷贝,不能使原值发生任何变化*/
m=2*n-1; /*要使原值变化,应传递引用方式(int &a,int &b)或传址方式(&a,&b)*/
ht=(hnode *)malloc(m*sizeof(hnode));/*而PRINT函数不一样它做的是输出,既能用传值也可传址,或引用方式,因为不需要对原值产生变化*/
for(p=ht,i=0;i<n;++i,++p,++w)
{
p->weight=*w;p->lchild=-1;
p->rchild=-1;p->parent=-1;
}
for(;i<m;++i,++p)
{
p->weight=0;p->lchild=-1;
p->rchild=-1;p->parent=-1;
}
for(i=n;i<m;++i)/*构造哈弗曼树*/
{
m1=m2=MAXVALUE;
x1=x2=0;
for(j=0;j<i;++j)
{
if(ht[j].parent==-1&&ht[j].weight<m1)
{
m2=m1;x2=x1;m1=ht[j].weight;x1=j;
}
else if(ht[j].parent==-1&&ht[j].weight<m2)
{
m2=ht[j].weight;x2=j;
}
}
ht[x1].parent=i;ht[x2].parent=i;
ht[i].lchild=x1;ht[i].rchild=x2;
ht[i].weight=m1+m2;
}
/*字符编码*/
*hc=(hcode *)malloc(n*sizeof(hcode));
cd=(char *)malloc(n*sizeof(char));
cd[n-1]='\0';
for(i=0;i<n;++i)
{
start=n-1;
for(c=i,f=ht[i].parent;f!=-1;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);
}
int count(char *s,int cnt[],char str[])
{
char *p;
int i,j,k;
int temp[29];
for(i=0;i<29;i++) temp[i]=0;
for(p=s; *p!='\0';p++)
{
if(*p>='a'&& *p<='z')
{
k=(*p)-97;
temp[k]++;
}
else if(*p==',')
{
k=(*p)-18;
temp[k]++;
}
else if(*p=='.')
{
k=(*p)-19;
temp[k]++;
}
else if(*p==' ')
{
k=(*p)-4;
temp[k]++;
}
}
for(i=0,j=0;i<29;i++)
{
if(temp[i]!=0)
{
if(i<26)
{
str[j]=i+97;
cnt[j]=temp[i];
j++;
}
else if(i==26)
{
str[j]=i+18;
cnt[j]=temp[i];
j++;
}
else if(i==27)
{
str[j]=i+19;
cnt[j]=temp[i];
j++;
}
else if(i==28)
{
str[j]=i+4;
cnt[j]=temp[i];
j++;
}
}
}
str[j]='\0';
return j;
}
void print(hcode *hc,char str[],int n)
{
int i;
for(i=0;i<n;i++)
{
printf(" %c->: ",str[i]);
puts(hc[i]);
putchar('\n');
}
return;
}
void coding(hcode **hc,char *s,char str[])
{
int i,j;
char *cp;
FILE *fp;
fp=fopen("d:\\codefile.txt","w");
while(*s)
{
for(i=0;i<MAXSIZE;i++)
if(str[i]==*s)
{
for(j=0,cp=(*hc)[i];j<(int)strlen((*hc)[i]);j++,cp++)
fputc(*cp,fp);
break;
}
s++;
}
fclose(fp);
}
char *decode(hcode **hc,char str[],int num)
{
FILE *fp;
char s[254];
char *p;
static char cd[MAXBIT+1];
int i,j,k=0,cjs;
fp=fopen("d:\\codefile.txt","r");
while(!feof(fp))
{
cjs=0;
for(i=0;i<MAXSIZE&&cjs==0&&!feof(fp);i++)
{
cd[i]=' ';cd[i+1]='\0';
cd[i]=fgetc(fp);
for(j=0;j<num;j++)
if(strcmp((*hc)[j],cd)==0)
{
s[k]=str[j];
k++;
cjs=1;
break;
}
}
}
s[k]='\0';
p=s;
return p;
}
void main()
{
char st[254],*s,str[29];
int cn[29],num;
hnode ht;
hcode *hc;
printf("input the setense:\n");
gets(st);
num=count(st,cn,str);
huffmancoding(&ht,&hc,cn,num);
print(hc,str,num);
coding(&hc,st,str);
s=decode(&hc,str,num);
printf("%s\n",s);
}
那些年我写的哈夫曼树(i love you.)
最新推荐文章于 2024-03-12 15:31:51 发布