跪求编程高手帮助!!!哈夫曼树相关~!50分!可以追加

2025-03-03 18:16:20
推荐回答(1个)
回答1:

#include
#include
#include
#include
#include
#include

typedef struct
{
int weight;
int parent,lchild,rchild;
}HTNode,* HuffmanTree;//哈夫曼结构

typedef char **HuffmanCode;//哈夫曼编码

HuffmanTree HT;
HuffmanCode HC;
int *w,i=0,j=0,n=0,number=0;
char *z;

void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n)//W存放N个字符的权值,构造哈夫曼树HT,并求出N个字符的哈夫曼编码HC
{
int m,i,s1,s2,start;
int c,f;
HuffmanTree p;
char *cd;
if(n<=1)
return;
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
for(p=HT+1,i=1;i<=n;++i,++p,++w)//初使化前n个结点,将权值放入每个结点中
{
p->weight=*w;
p->parent=0;
p->lchild=0;
p->rchild=0;
}
for(;i<=m;++i,++p)//初使化n+1到m个结点的parent值
p->parent=0;
for(i=n+1;i<=m;++i)//建树
{
j=1;
p=HT;
while((j<=i-1)&&(p[j].parent!=0))//未建结点个数
j++;
s1=j;
while(j<=i-1)
{
if(p[j].parent==0&&p[j].weight s1=j;
j++;
}
p[s1].parent=i;
j=1;
p=HT;
while(j<=i-1&&p[j].parent!=0)//剩余未建结点个数
j++;
s2=j;
while(j<=i-1)
{
if(p[j].parent==0&&p[j].weight s2=j;
j++;
}
if(s1>s2)
{
j=s1;
s1=s2;
s2=j;
}
HT[s1].parent=HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}

//从叶子到根逆向求每个字符的哈夫曼编码
HC=(HuffmanCode)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)//左0右1编码
cd[--start]='0';
else
cd[--start]='1';
HC[i]=(char*)malloc((n-start)*sizeof(char));
strcpy(HC[i],&cd[start]); //复制串
}
free(cd);
}

void Initialization()//初使化,从终端读入字符集大小n,以及n个字符和n个权值,建树,并存入文件中
{

int num;
int quan;
cout<<"请输入字符集个数:";
cin>>num;
n=num;
w=(int*)malloc(n*sizeof(int));//存放权
z=(char*)malloc(n*sizeof(char));//存放字符
cout<<"请依次输入"< char cs[2];
for(i=0;i {
cout<<"第"< cin>>cs;
*(z+i)=*cs;
}

cout< for(i=0;i<=n-1;i++)//存放权
{
cout<<"第"< cin>>quan;
*(w+i)=quan;
}
cout<<"字母表为";
for(i=0;i<=n-1;i++)
{
cout< }
cout<
cout<<"权值表为";
for(i=0;i<=n-1;i++)
{
cout< }

HuffmanCoding(HT,HC,w,n);//建树,编码

cout< for(i=1;i<=n;i++)
{
cout<<*(z+i-1)<<"............................";
cout< }

//存入文件htmTree中
FILE *htmTree;
char rt[]={' ','\0'};
if((htmTree=fopen("htmTree.txt","w"))==NULL)
{
cout<<"can not open file"< return;
}

fputs(z,htmTree);
for(i=0;i {
fprintf(htmTree,"%5d",*(w+i));
fputs(rt,htmTree);
}
for(i=1;i<=n;i++)
{
fputs(HC[i],htmTree);
fputs(rt,htmTree);
}
fclose(htmTree);

}

void InputMessage()//输入要编译的报文,并将其存入文件tobetran中
{

FILE *tobetran;
char mess[40];
if((tobetran=fopen("tobetran.txt","w"))==NULL)
{
cout<<"不能打开文件"< return;
}
cout<<"请输入想要编码"< gets(mess);
fputs(mess,tobetran);
fclose(tobetran);
}

void Coding()//读取tobetran中的报文,并编码后存入文件codefile中
{
FILE *tobetran,*codefile;
if((tobetran=fopen("tobetran.txt","rb"))==NULL)
cout<<"不能打开文件"< if((codefile=fopen("codefile.txt","wb"))==NULL)
cout<<"不能打开文件"<
char *tran;//中间变量
tran=(char*)malloc(100*sizeof(char));
int i=1;
while(i==1)
{
if(fgets(tran,100,tobetran)==NULL)
{
cout<<"不能打开文件"< break;
}//将tobetran中读取的字符存入tran中
for(i=0;*(tran+i)!='\0';i++)
{
for(j=0;j<=n;j++)
{
if(*(z+j-1)==*(tran+i))//找到第i个字符对应在Z中的位置
fputs(HC[j],codefile);//编码并存入codefile中

}
}
}

fclose(tobetran);
fclose(codefile);
free(tran);
}

void Decoding()//利用已建好的哈夫曼树将codefile中的代码进行译码,并将结果存入文件txtfile中
{
FILE *codef,*txtfile;
if((txtfile=fopen("Textfile.txt","w"))==NULL)
cout<<"不能打开文件"< if ((codef=fopen("codefile.txt","r"))==NULL)
cout<<"不能打开文件"<
char w[1000],v[1000];
int j=0,i=0,m=0;

fgets(w,2000,codef);//将编码存入W中
m=2*n-1;
for(i=0;*(w+i-1)!='\0';i++)
{
if(HT[m].lchild==0&&HT[m].rchild==0) //,无孩子,是叶子结点
{
*(v+j)=*(z+m-1);//找到字符
j++;
m=2*n-1;
i--;
}
else if(*(w+i)=='0') m=HT[m].lchild;//有孩子
else if(*(w+i)=='1') m=HT[m].rchild;
}
*(v+j+1)='\0';
fputs(v,txtfile);//将字符存入文件夹中
fclose(txtfile);
fclose(codef);

}

void Pcode()//将codefile以紧凑可式显式在终端上,每行50个代码,结果存入 CodePrin中
{

FILE * CodePrin,* codefile;
if((CodePrin=fopen("CodePrin.txt","w"))==NULL)
{
cout<<"不能打开文件"< return;
}
if((codefile=fopen("codefile.txt","r"))==NULL)
{
cout<<"不能打开文件"< return;
}

char *q;
//char *y='\r';
q=(char*)malloc(51*sizeof(char));//存50个字符

do
{//将codefile中的每50个字符存入q中
if(fgets(q,51,codefile)==NULL)
{
cout<<"不能读取文件"< break;
}
fputs(q,CodePrin);
//fputs(y,CodePrin);
puts(q);
}while(strlen(q)==50);

free(q);
fclose(CodePrin);
fclose(codefile);
}

void Print(HuffmanTree p,HuffmanTree HT)//打印哈夫曼树,并将其存入TreePrint中
{

if(p!=HT)
{
FILE * TreePrint;
if((TreePrint=fopen("TreePrint.txt","a"))==NULL)
{
cout<<"创建文件失败"< return;
}

number++;
Print(HT+p->rchild,HT);
cout<weight<
fprintf(TreePrint,"%d\n",p->weight);
Print(HT+p->lchild,HT);
number--;
fclose(TreePrint);
}
}

void main()
{
char a;
while(a!='Q')
{
cout<<"请选择要执行的命令:"< cout<<"I 初使化,建立哈夫曼树; S 输入翻译的报文; E 对报文编码;"< cin>>a;
switch(a)
{
case'I':
Initialization();//初使化,建立哈夫曼树
break;
case'S':
InputMessage();//输入要翻译的报文
break;
case'E':
Coding();//读取报文并编码
break;
case'D':
Decoding();//将代码进行译码
break;
case'P':
cout<<"打印编码"< Pcode();
break;
case'T':
cout<<"打印哈夫曼树"< Print(HT+2*n-1,HT);//打印哈夫曼树
cout<<"原文,编码和译码结果可在文件中查找。";
break;
}
}
free(z);
free(w);
free(HT);

}
前几天上机刚好做了这个,完全符合你的要求,你不会也是西电的学生吧……题目和我们数据结构一模一样的,一定要给我分呀!