问答题

【预备知识】 ①对给定的字符集合及相应的权值,采用哈夫曼算法构造最优二叉树,并用结构数组存储最优二叉树。例如,给定字符集合{a,b,c,d}及其权值2、7、4、5,可构造如图5-6所示的最优二叉树和相应的结构数组Ht(数组元素Ht[0]不用)。
结构数组Ht的类型定义如下: #define MAXLEAFNUM 20 struct node{ char ch; /*当前节点表示的字符,对于非叶子节点,此域不用*/ int weight; /*当前节点的权值*/ int parent; /*当前节点的父节点的下标,为0时表示无父节点*/ int lchild,rchild; /*当前节点的左、右孩子节点的下标,为0时表示无对应的孩子节点*/ }Ht[2*MAXLEAFNUM]; ②用“0”或“1”标识最优二叉树中分支的规则是:从一个节点进入其左(右)孩子节点,就用“0”(“1”)标识该分支(示例见图5-6)。 ③若用上述规则标识最优二叉树的每条分支后,从根节点开始到叶子节点为止,按经过分支的次序,将相应标识依次排列,可得到由“0”、“1”组成的一个序列,称此序列为该叶子节点的前缀编码。例如图5-6所示的叶子节点a、b、c、d的前缀编码分别是110、0、111、10。 【函数5-6说明】 函数void LeafCode(int root,int n)的功能是:采用非递归方法,遍历最优二叉树的全部叶子节点,为所有的叶子节点构造前缀编码。其中形参root为最优二叉树的根节点下标,形参n为叶子节点个数。 在构造过程中,将Ht[P].weight域用做被遍历节点的遍历状态标志。 【函数5-6】 char **Hc; void LeafCode(int root, int n) /*为最优二叉树中的n个叶子节点构造前缀编码,root是树的根节点下标*/ { int i,p=root,cdlen=0; char code[20]; Hc=(char**)maloc((n+1)*sizeof(char*)); /*申请字符指针数组*/ for(i=1;i<=p;++i) Ht[i].weight=0; /*遍历最优二叉树时用做被遍历节点的状态标志*/ while(p){ /*以非递归方法遍历最优二叉树,求树中每个叶子节点的编码*/ if(Ht[p].weight==0){/*向左*/ Ht[p].weight=1; if(Ht[p].lchild !=0){ p=Ht[p].lchild; code[cdlen++]=’0’; }else if(Ht[p].rchild==0){ /*若是叶子节点,则保存其前缀编码*/ Hc[p]=(char *)malloc((cdlen+1)*sizeof(char)); (1) ; strcpy(Hc[p],code); } }else if(Ht[p].weight==1)(/*向右*/ Ht[p].weight=2; if(Ht[p].rchild !=0){ p=Ht[p].rchild; code[edlen++]=’1’; } }else { /*Ht[p].weight==2,回退*/ Ht[p].weight=0; p= (2) ; (3) ; /*退回父节点*/ } }/*while结束*/ } 【函数5-7说明】 函数void Decode(char *buff,int root)的功能是:将前缀编码序列翻译成叶子节点的字符序列,并输出。其中形参root为最优二叉树的根节点下标,形参buff指向前缀编码序列。 【函数5-7】 void Decode(char *buff,int root) { int pre=root,p; while(*buff !=’\0’){ p=root; while(p !=0){/* 存在下标为p的节点*/ pre=p; if( (4) )p=Ht[p].lchild; /*进入左子树*/ else p=Ht[p].rchild; /*进入右子树*/ buff++; /*指向前缀编码序列的下一个字符*/ } (5) ; printf("%c",Ht[pre].ch); } }

【参考答案】

(1) [cdlen]=’\0’或code[cdlen]=0 (2) Ht[p].parent (3) --cdlen或......

(↓↓↓ 点击下方‘点击查看答案’看完整答案 ↓↓↓)
热门 试题

问答题
【说明】函数int Toplogcal(LinkedWDigraph G)的功能是对图G中的顶点进行拓扑排序,并返回关键路径的长度。其中图G表示一个具有n个顶点的AOE网,图中顶点从1~n依次编号,图G的存储结构采用邻接表表示,其数据类型定义如下:typedef struct Gnode{ *邻接表的表节点类型* int adjvex; *邻接顶点编号* int weieht; *弧上的权值* stract Gnode *nextarc; *指示下一个弧的节点* }Gnode;typedef struct Adjlist{ *邻接表的头节点类型* char vdata; *顶点的数据信息* struct Gnode *Firstadj; *指向邻接表的第一个表节点* }Adjlist;typedef struct LinkedWDigraph{ *图的类型* int n,e; *图中顶点个数和边数* struct Adjlist *head; *指向图中第一个顶点的邻接表的头节点* }LinkedWDigraph;例如,某AOE网如图5-4所示,其邻接表存储结构如图5-5所示。int Toplogical(LinkedWDigraph G){Gnode *p;int j,w,top=0;int *Stack,*ve,*indegree;ve=(int*)malloc((G.n+1)*sizeof(int));indegree=(int*)malloc((G.n+1)*sizeof(int)); *存储网中各顶点的入度* Stack=(int*)malloe((G.n+1)*sizeof(int)); *存储入度为0的顶点的编号* if(!ve||!indegree||!Stack)exit(0);for(j=1;j<=G.n;j++){ve[j]=0;indegree[j]=0;} *for* for(j=1;j<=G.n;j++){ *求网中各顶点的入度* p=G.head[j].Firstadj;while(p){(1) ;p=p->nextarc;} *while* } *for* for(j=1;j<=G.n;j++) *求网中入度为0的顶点并保存其编号* if(!indegree[j])Stack[++top]=j;while(top>0){w= (2) ;printf( %c ,G.head[w].vdata);p=G.head[w].Firstadj;while(p){(3) ;if(!indegree[p->adjvex])Stack[++top]=p->adjvex;if( (4) )ve[p->adjvex]=ve[w]+p->weight;p=p->nextarc;} *while* } *while* return (5) ;} *Toplogical*