永发信息网

C语言数据结构中的哈弗曼树

答案:2  悬赏:0  手机版
解决时间 2021-04-26 06:45

帮我说明一下这个程序,和这个程序的编译后的输出结果是怎么回事,都表示什么,细点讲。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define n 8
#define m 2*n-1
#define max 2000
typedef struct
{
int wi;
char data;
int Parent,Lchild,Rchild;
}huffm;
huffm HT[m+1];
typedef struct
{
char bits[n+1];
int start;
char ch;
}ctype;
void HuffmTree(huffm HT[m+1]);
void Huffmcode(ctype code[n+1]);
void Output (ctype code[n+1]);
void HuffmTree(huffm *HT)
{
int i,j,p1,p2,w;
int s1,s2;
for(i=n+1;i<=m;i++)
{
p1=p2=0;
s1=s2=max;
for(j=1;j<=i-1;j++)
if(HT[j].Parent ==0)
if(HT[j].wi <s1)
{
s2=s1;
s1=HT[j].wi;
p2=p1; p1=j;
}
else if(HT[j].wi<s2)
{
s2=HT[j].wi ;
p2=j;
}
HT[p1].Parent = HT[p2].Parent =i;
HT[i].Lchild =p1;
HT[i].Rchild =p2;
HT[i].wi =HT[p1].wi + HT[p2].wi ;
}
printf("\n OK!");
for(i=1;i<=m;i++)
{
printf("\n");
printf("%d ",HT[i].wi);
}
getchar();
return ;
}
void Huffmcode(ctype code[n+1])
{
int i,p,s;
ctype md;
for(i=1;i<=n;i++)
{
md.ch = code[i].ch;
md.start = n+1;
s = i;
p = HT[i].Parent;
while(p!=0)
{
md.start--;
if(HT[p].Lchild ==s)
md.bits[md.start]='0';
else
md.bits[md.start] ='1';
s=p;
p=HT[p].Parent;
}
code[i] = md;
}
}
void Output(ctype code[n+1])
{
int i,j;
for(i=1;i<=n;i++)
{
printf("\n");
printf("%c ",code[i].ch );
for(j=1;j<=8;j++)
{
if(j<code[i].start)
printf(" ");
else
if((code[i].bits[j] == '0')||(code[i].bits[j] == '1'))
printf("%c",code[i].bits[j]);
}
printf(" %d",code[i].start);
}
}
void main()
{
int i,j;
int w;
int flag=1;
int choice;
ctype code[n+1];
char temp[n+1];
int temp2[n+1];
clrscr();
printf("Would you want to play?(1-Yes and Start/0-No and Exit)");
scanf("%d",&choice);
while(flag&&(choice==1))
{
choice = 0;
for(i=1;i<=m;i++)
{
HT[i].data =NULL;
HT[i].wi=0;
HT[i].Parent = 0;
HT[i].Lchild = HT[i].Rchild = 0;
}
for(i=1;i<=n;i++)
{
code[i].start = 0;
code[i].ch = NULL;
for(j=1;j<=n;j++)
code[i].bits[j] = NULL;
}
printf("Please input %d char: \n",n);
getchar();
scanf("%c %c %c %c %c %c %c %c",&temp[1],&temp[2],&temp[3],&temp[4],&temp[5],&temp[6],&temp[7],&temp[8]);
for(i=1;i<=n;i++)
{
code[i].ch =temp[i];
HT[i].data =temp[i];
}
printf("Please input %d rate: \n",n);
getchar();
scanf("%d %d %d %d %d %d %d %d",&temp2[1],&temp2[2],&temp2[3],&temp2[4],&temp2[5],&temp2[6],&temp2[7],&temp2[8]);
for(i=1;i<=n;i++)
{
w= temp2[i];
HT[i].wi = w;
}
HuffmTree(HT);
Huffmcode(code);
Output(code);
printf("\nContinue?1-Contine,0-Exit\n");
scanf("%d",&choice);
if(choice!=1)
break;
}
return;
}

最佳答案













typedef struct


{


char ch; //字母与编码


int weight; //权重


int parent,lchild,rchild; //父亲与左右孩子


}HTNode,*HuffmanTree;


typedef char **HuffmanCode;


//函数原型声明


//构造HuffmanTree


void CreateHuffmanTree(HuffmanTree &HT,int w[],char ch[],int n);


//选择两个权重最小的无父亲的结点


void Select(HuffmanTree HT,int n, int &s1, int &s2);


//利用HuffmanTree对字符编码


void HTCoding(HuffmanTree HT,HuffmanCode &HC,int n);


void PrintCode(HuffmanCode HC,int n,char ch[]);//输出编码


//求平均编码长度


double AverageLenght(HuffmanCode HC,int n); //求平均编码长度


void DeCode(HuffmanTree HT,int n);//解码



#include <stdio.h>


#include <stdlib.h>


#include <malloc.h>


#include <string.h>



typedef struct


{


char ch; //字母与编码


int weight; //权重


int parent,lchild,rchild; //父亲与左右孩子


}HTNode,*HuffmanTree;


typedef char **HuffmanCode;


//函数原型声明


//构造HuffmanTree


void CreateHuffmanTree(HuffmanTree &HT,int w[],char ch[],int n);


//选择两个权重最小的无父亲的结点


void Select(HuffmanTree HT,int n, int &s1, int &s2);


//利用HuffmanTree对字符编码


void HTCoding(HuffmanTree HT,HuffmanCode &HC,int n);


void PrintCode(HuffmanCode HC,int n,char ch[]);//输出编码


//求平均编码长度


double AverageLenght(HuffmanCode HC,int n); //求平均编码长度


void DeCode(HuffmanTree HT,int n);//解码



void main()


{



int n;


int i;


char arrch[20];


int arrweight[20];


double avlength;


char ch;


HuffmanTree HT; //HT是一个指针变量,用于指向HuffmanTree


HuffmanCode HC; //HC是一个指针变量,用于存放对应字符的编码


scanf("%d",&n);//输入字符个数


while((ch=getchar())!='\n');


if(n>20||n<2) exit(0); //输入的字符数超出要求范围退出;


for(i=0;i<n;i++) //输入字符和对应的权重


{


scanf("%c",&arrch[i]);


scanf("%d",&arrweight[i]);


while((ch=getchar())!='\n');


}


CreateHuffmanTree(HT,arrweight,arrch,n);//构造HuffmanTree


HTCoding(HT,HC,n);//利用HuffmanTree对字符编码


PrintCode(HC,n,arrch); //输出编码


avlength=AverageLenght(HC,n);//求平均编码长度


printf("平均编码长度为:%f\n",avlength);


DeCode(HT,n);//解码


//释放申请的空间


for(i=0;i<n;i++)


free(HC[i]);


free(HC);


free(HT);


}//end_main



//构造HuffmanTree


void CreateHuffmanTree(HuffmanTree &HT,int w[],char ch[],int n)


{


// w存放n个字符的权值(均>0),构造哈夫曼树HT,


int i, m, s1, s2;


m = 2 * n - 1;


HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode)); // 0号单元不用


//设有一组权值存放于数组w[]中,对应的字符在数组ch[]中


for (i=1; i<=n; i++)


{


HT[i].weight=w[i-1];


HT[i].parent=0;


HT[i].lchild=0;


HT[i].rchild=0;



HT[i].ch =ch[i-1];



}


//数组HT后n-1个元素先清空


for (i=n+1; i<=m; i++)


{


HT[i].weight=0;


HT[i].parent=0;


HT[i].lchild=0;


HT[i].rchild=0;


HT[i].ch='\0';



}


for (i=n+1; i<=m; i++) // 建哈夫曼树


{


// 在HT[1..i-1]中选择parent为0且weight最小的两个结点,


// 其序号分别为s1和s2。


Select(HT, i-1, s1, s2);


HT[s1].parent = i; HT[s2].parent = i;


HT[i].lchild = s1; HT[i].rchild = s2;


HT[i].weight = HT[s1].weight + HT[s2].weight;


}



} //end_HuffmanCoding


//选择两个权重最小的无父亲的结点,且下标s1对应的权小于等于s2的权


void Select(HuffmanTree HT,int n, int &s1, int &s2)


{ //补充完整



}//end_Select



//利用HuffmanTree对字符编码


void HTCoding(HuffmanTree HT,HuffmanCode &HC,int n)


{


//--- 从叶子到根逆向求每个字符的哈夫曼编码 ---


int i,j,k, start;


int f;


int c;


char * cd;



HC=(HuffmanCode)malloc((n)*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-1]=(char *)malloc((n-start)*sizeof(char));


// 为第i个字符编码分配空间


for(j=start,k=0;j<n;j++,k++)// 从cd复制编码(串)到HC


HC[i-1][k]=cd[j];



}


free(cd); // 释放工作空间



}//end_HTCoding




void PrintCode(HuffmanCode HC,int n,char ch[]) //输出编码


{ //补充完整



}//end_PrintCode



double AverageLenght(HuffmanCode HC,int n)//求平均编码长度


{//补充完整



}//end_AverageLenght



void DeCode(HuffmanTree HT,int n)//解码


{


int i;


char endflag='#';


char ch;


i=2*n-1;


scanf("%c",&ch);


while (ch!=endflag)


{


if (ch=='0')


i=HT[i].lchild;


else i=HT[i].rchild;



if(HT[i].lchild==0)


{


printf("%c",HT[i].ch);


i=2*n-1;


}


scanf("%c",&ch);


}


if ((HT[i].lchild!=0) && (i!=2*n-1)) //电文读完但没到叶子结点


printf("\n未能完全解码\n");


printf("\n");


}//end_DeCode











输入示例:


5


A 8


B 20


C 30


D 15


E 27


0101101110#


(说明:第一个数据5表示共有5个字符要编码,后面的“A 8”表示A的权为8,字符个数不超过20个;数据0101101110#是要解码的数据,最后以#结束)



输出示例:


编码为:A 010


B 00


C 11


D 011


E 10


平均编码长度为:2.40


对应的译码为:ACDE


全部回答
你好哦楼主~ 很高兴看到你的问题。 但是又很遗憾到现在还没有人回答你的问题。也可能你现在已经在别的地方找到了答案,那就得恭喜你啦。 可能是你问的问题有些专业了,没人会。或者别人没有遇到或者接触过你的问题,所以帮不了你。建议你去问题的相关论坛去求助,那里的人通常比较多,也会比较热心,能快点帮你解决问题。 希望我的回答能够帮到你! 祝你好运。。
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
BOBO组合真的要单飞了吗?
DNF44级大那里经验最多?
珠江码头在哪里啊,我有事要去这个地方
储蓄卡可以办副卡吗,多大年龄可以办银行卡?
英雄岛为什么我和我朋友的好友度4223第二天上
炫舞 爱恋时长是什么意思
心脏房颤遗传吗?
现在有什么赚钱快的?
体育素质测试成绩对就业有影响吗?
颜色中七大代表的颜色分别哪七种色?又有什么
杨厂血防组门诊部这个地址在什么地方,我要处
关于不遵守网游规定的检讨书
哪里可以下载世界杯主题曲,手机网站
我没有生病也没有吃避孕药为什么我的月经到现
普通店能转为旺铺店吗
推荐资讯
这句话运用了什么修辞,有什么作用?
北京哪里有麦考林服装店?谢谢!
我的e家电视机显示1403错误,说账号和密码错
对外财务报表都有哪些,三大财务报表是什么,
天国的邮递员在驻马店有卖吗?
新乡到铁岭的火车什么时候有啊?
生物自测习题
求重阳节的配乐诗朗诵
混乱军团硬盘版
洋中派出所(中心街)地址在哪,我要去那里办事
大一怎么追女生?
喝酒是否可以解除寂寞?
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?