永发信息网

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

答案:2  悬赏:0  手机版
解决时间 2021-04-26 06:45
  • 提问者网友:骨子里的高雅
  • 2021-04-25 09:48

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

#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;
}

最佳答案
  • 五星知识达人网友:杯酒困英雄
  • 2021-04-25 10:32













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


全部回答
  • 1楼网友:独行浪子会拥风
  • 2021-04-25 11:59
你好哦楼主~ 很高兴看到你的问题。 但是又很遗憾到现在还没有人回答你的问题。也可能你现在已经在别的地方找到了答案,那就得恭喜你啦。 可能是你问的问题有些专业了,没人会。或者别人没有遇到或者接触过你的问题,所以帮不了你。建议你去问题的相关论坛去求助,那里的人通常比较多,也会比较热心,能快点帮你解决问题。 希望我的回答能够帮到你! 祝你好运。。
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯