阅读以下函数说明和C代码,将C程序中(1)~(5)空缺处的内容补充完整。【说明】对给定的字符集合及相应的权值,采用哈夫曼算法构造最优二叉树,并用结构数组存储最优二叉树。例如,给定字符集合{a,b,c,d}及其权值2、7、4、5,可构造如图6-15所示的最优二叉树,以及相应的结构数组Ht(如表6-14所示,其中数组元素Ht[0]不用)。结构数组Ht的类型定义如下:define MAXLEAFNUM 20struct node{char ch; /*扫当前节点表示的字符,对于非叶子节点,此域不用*/Int w

题目

阅读以下函数说明和C代码,将C程序中(1)~(5)空缺处的内容补充完整。

【说明】

对给定的字符集合及相应的权值,采用哈夫曼算法构造最优二叉树,并用结构数组存储最优二叉树。例如,给定字符集合{a,b,c,d}及其权值2、7、4、5,可构造如图6-15所示的最优二叉树,以及相应的结构数组Ht(如表6-14所示,其中数组元素Ht[0]不用)。

结构数组Ht的类型定义如下:

define MAXLEAFNUM 20

struct node{

char ch; /*扫当前节点表示的字符,对于非叶子节点,此域不用*/

Int weight; /*当前节点的权值*/

int parent; /*当前节点的父节点的下标,为0时表示无父节点*/

int lchild, rchild;

/*当前节点的左、右孩子节点的下标,为0时表示无对应的孩子节点*/

)Ht[2*MAXLEAFNUM];

用“0”或“广标识最优二叉树中分支的规则是:从一个节点进入其左(右)孩子节点,就用“0”(或“1”)标识该分支,如图6-15所示。

若用上述规则标识最优二叉树的每条分支后,从根节点开始到叶子节点为止,按经过分支的次序将相应标识依次排列,可得到由“0”、“1”组成的一个序列,称此序列为该叶子节点的前缀编码。例如,图6-15所示的叶子节点a、b、c、d的前缀编码分别是110、0、111、10。

函数void LeafCode(int root,int n)的功能是:采用非递归方法,遍历最优二叉树的全部叶子节点,为所有的叶子节点构造前缀编码。其中,形参root为最优二叉树的根节点下标;形参n为叶子节点个数。在函数void LeafCode(int root,int n)构造过程中,将Ht[p].weight域用做被遍历节点的遍历状态标志。

函数void Decode(char *buff,int root)的功能是:将前缀编码序列翻译成叶子节点的字符序列,并输出。其中,形参root为最优二叉树的根节点下标;形参buff指向前缀编码序列。

【函数4.1】

char **HC;

void LeafCode(int root, int n)

{ /*为最优二叉树中的n个叶子节点构造前缀编码,root是树的根节点下标*/

int I,p=root,cdlen=0;

char code[20];

Hc = (char **)malloc((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[cdlen++] ='1';

}

}

else { /*Ht[p].weight == 2,回退/

Ht [p].weight = 0;

p =(2);

(3); /*退回父节点*/

}

} / *while .结束* /

}

【函数4.2】

void Decode(char *buff,int root)

{ int pre = root,p;

while(*buff != '\0') {

p = root;

&


相似考题
更多“ 阅读以下函数说明和C代码,将C程序中(1)~(5)空缺处的内容补充完整。【说明】对给定的字符集合及相应的权值,采用哈夫曼算法构造最优二叉树,并用结构数组存储最优二叉树。例如,给定字符集合{a,b,c,d}及其权值”相关问题
  • 第1题:

    阅读以下预备知识、函数说明和C代码,将应填入(n)处的字句写在对应栏内。

    [预备知识]

    ①对给定的字符集合及相应的权值,采用哈夫曼算法构造最优二叉树,并用结构数组存储最优二叉树。例如,给定字符集合{a,b,c,d}及其权值2、7、4、5,可构造如图3所示的最优二叉树和相应的结构数组Ht(数组元素Ht[0]不用)(见表5)。

    结构数组HT的类型定义如下:

    define MAXLEAFNUM 20

    struct node {

    char ch; / * 当前结点表示的字符,对于非叶子结点,此域不用*/

    int weight; / * 当前结点的权值*/

    int parent; / * 当前结点的父结点的下标,为0时表示无父结点*/

    int Ichild, rchild

    / *当前结点的左、右孩子结点的下标,为0时表示无对应的孩子结点* /

    } Ht[2 * MAXLEAFNUM];

    ②用'0'或'1'标识最优二叉树中分支的规则是:从一个结点进入其左(右)孩子结点,就用'0'('1')标识该分支(示例如图3所示)。

    ③若用上述规则标识最优二叉树的每条分支后,从根结点开始到叶子结点为止,按经过分支的次序,将相应标识依次排列,可得到由'0'、'1'组成的一个序列,称此序列为该叶子结点的前缀编码。如图3所示的叶子结点a、b、c、d的前缀编码分别是110、0、111、10。

    【函数5.1说明】

    函数void LeafCode (int root, int n)的功能是:采用非递归方法,遍历最优二叉树的全部叶子结点,为所有的叶子结点构造前缀编码。其中形参root为最优二叉树的根结点下标;形参 n为叶子结点个数。

    在构造过程中,将Ht[p]. weight域用作被遍历结点的遍历状态标志。

    【函数5.1】

    char * * Hc;

    void LeafCode (int root, int n)

    {/*为最优二叉树中的n个叶子结点构造前缀编码,root是树的根结点下标* /

    int i,p = root,cdlen =0;char code[20];

    Hc=(char* * )malloc(.(n +]) *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(He[ p] ,code);

    }

    }

    else if (Ht[ pi, weight == 1) { /*向右*/

    Ht[p]. weight =2;

    if(Ht[p].rchild !=0) {p=Ht[p].rchild; code[cdlen++] ='1';}

    }

    else{/* Ht[p]. weight ==2,回退*/

    Ht[p]. weight =0;

    p=(2);(3); /*退回父结点*/

    }

    }/* while结束* /

    }

    【函数5.2说明】

    函数void Decode(char*buff, int root)的功能是:将前缀编码序列翻译成叶子结点的字符序列并输出。其中形参root为最优二叉树的根结点下标;形参buff指向前缀编码序列。

    【函数5.2】

    void Decode( char * buff, int root)

    Iint 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)code[cdlen]='\0'或code[cdlen]=0(2)Ht[p].par- ent (3)--cdlen或等价形式(4)*buff=='0'或等价形式 (5)buff--或等价形式
    (1)code[cdlen]='\0'或code[cdlen]=0(2)Ht[p].par- ent (3)--cdlen或等价形式(4)*buff=='0'或等价形式 (5)buff--或等价形式 解析:(1)根据注释的提示,可知此小段代码的作用是把code字符串保存起来,结合下一句,可知应给code字符串添加一个结束符'0'。(2)将指针指向当前结点的父结点。(3)将code指针前移一位。(4)如果前缀编码为,'0'进入左子树。(5)注意下一个语句,Prinf(“%c”,Ht[pre].ch);其参数是pre,内层循环中有pre=p,这样做的目的是当Ht[p].lchild或 Ht[p]. rchild等于0时,不把这—层链人结果。

  • 第2题:

    ●试题五

    阅读以下预备知识、函数说明和C代码,将应填入(n)处的字句写在答题纸的对应栏内。

    【预备知识】

    ①对给定的字符集合及相应的权值,采用哈夫曼算法构造最优二叉树,并用结构数组存储最优二叉树。例如,给定字符集合{a,b,c,d}及其权值2、7、4、5,可构造如图3所示的最优二叉树和相应的结构数组Ht(数组元素Ht[0]不用)(见表5)。

    图3最优二叉树

    表5 结构数组Ht

    结构数组Ht的类型定义如下:

    define MAXLEAFNUM 20

    struct node{

    char ch;/*当前结点表示的字符,对于非叶子结点,此域不用*/

    int weight;/*当前结点的权值*/

    int parent;/*当前结点的父结点的下标,为0时表示无父结点*/

    int lchild,rchild;

    /*当前结点的左、右孩子结点的下标,为0时表示无对应的孩子结点*/

    }Ht[2*MAXLEAFNUM];

    ②用′0′或′1′标识最优二叉树中分支的规则是:从一个结点进入其左(右)孩子结点,就用′0′(′1′)标识该分支(示例如图3所示)。

    ③若用上述规则标识最优二叉树的每条分支后,从根结点开始到叶子结点为止,按经过分支的次序,将相应标识依次排列,可得到由′0′、′1′组成的一个序列,称此序列为该叶子结点的前缀编码。例如图3所示的叶子结点a、b、c、d的前缀编码分别是110、0、111、10。

    【函数5.1说明】

    函数void LeafCode(int root,int n)的功能是:采用非递归方法,遍历最优二叉树的全部叶子结点,为所有的叶子结点构造前缀编码。其中形参root为最优二叉树的根结点下标;形参n为叶子结点个数。

    在构造过程中 ,将Ht[p].weight域用作被遍历结点的遍历状态标志。

    【函数5.1】

    char**Hc;

    void LeafCode(int root,int n)

    {/*为最优二叉树中的n个叶子结点构造前缀编码,root是树的根结点下标*/

    int i,p=root,cdlen=0;char code[20];

    Hc=(char**)malloc((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(He[p],code);

    }

    }

    else if (Ht[p].weight==1){/*向右*/

    Ht[p].weight=2;

    if(Ht[p].rchild !=0){p=Ht[p].rchild;code[cdlen++]=′1′;}

    }

    else{/*Ht[p].weight==2,回退*/

    Ht[p].weight=0;

    p= (2) ; (3) ;/*退回父结点*/

    }

    }/*while结束*/

    }

    【函数5.2说明】

    函数void Decode(char*buff,int root)的功能是:将前缀编码序列翻译成叶子结点的字符序列并输出。其中形参root为最优二叉树的根结点下标;形参buff指向前缀编码序列。

    【函数5.2】

    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)code[cdlen]=\0或code[cdlen]=0(2)Ht[p].parent(3)--cdlen或等价形式(4)*buff==0或等价形式(5)buff--或等价形式【解析】(1)根据注释的提示,可知此小段代码的作用是把code字符串保存起来,结合下一句,可知应给code字符串添加一个结束符/0。(2)将指针指向当前结点的父结点。(3)将code指针前移一位。(4)如果前缀编码为0进入左子树。(5)注意下一个语句,Prinf("%c",Ht[pre].ch);其参数是pre,内层循环中有pre=p,这样做的目的是当Ht[p].lchild或Ht[p].rchild等于0时,不把这一层链入结果。

  • 第3题:

    ( )是由权值集合{8,5,6,2}构造的哈夫曼树(最优二叉树)。


    答案:C
    解析:
    本题考查二叉树应用知识。构造最优二叉树的哈夫曼算法如下:①根据给定的n个权值{W1,W2,...,Wn},构成n棵二叉树的集合F={T1,T2,...,Tn},其中每棵二叉树Ti中只有一个带权为Wi的根结点,其左右子树均空。②在F中选取两棵权值最小的二叉树作为左、右子树构造一棵新的二叉树,置新构造二叉树的根结点的权值为其左、右子树根结点的权值之和。③从F中删除这两棵树,同时将新得到的二叉树加入到F中。重复②、③,直到F中只含一棵树时为止。这棵树便是最优二叉树(哈夫曼树)。根据题中给出的权值集合,构造哈夫曼树的过程如下图所示。

  • 第4题:

    最优二叉树(或哈夫曼树)是指权值为 W1, W2,。。。,Wn 的 n 个叶结点的二叉树中带权路径长度最小的二叉树。( )是哈夫曼树(叶结点中的数字为其权值)。

    A.

    B.

    C.

    D.


    正确答案:A

  • 第5题:

    最优二叉树(或哈夫曼树)是指权值为w1,w2,…,wn的n个叶结点的二叉树中带权路径长度最小的二叉树。( )是哈夫曼树(叶结点中的数字为其权值)。



    答案:A
    解析:
    本题考查数据结构基础知识。
    哈夫曼树又称为最优二叉树,是一类带权路径长度最短的树。
    树的带权路径长度(WPL)为树中所有叶子结点的带权路径长度之和,记为

    其中n为带权叶子结点数目,wk为叶子结点的权值,lk为根到叶子结点的路径长度。
    选项A所示二叉树的WPL=(2+4)*3+5*2+7*1=35
    选项B所示二叉树的WPL=(2+4+5+7)*2=36
    选项C所示二叉树的WPL=(5+7)*3+4*2+2*1=46
    选项D所示二叉树的WPL=(4+5)*3+7*2+2*1=43