问答题 【预备知识】 ①对给定的字符集合及相应的权值,采用哈夫曼算法构造最优二叉树,并用结构数组存储最优二叉树。例如,给定字符集合{a,b,c,d}及其权值2、7、4、5,可构造如图5-6所示的最优二叉树和相应的结构数组Ht(数组元素Ht[0]不用)。
【正确答案】
【答案解析】(1) [cdlen]='/0'或code[cdlen]=0 (2) Ht[p].parent (3) --cdlen或等价形式 (4) *buff=='0'或等价形式 (5) buff--或等价形式 [分析] 本题考查Huffman树最优前缀码的编码和译码。 函数5-6是用来为Huffman树的每个叶节点构造最优前缀码的,根据说明,实际上就是求从根节点到各叶节点的路径。程序对Huffman树进行前序遍历,将路径记录在code数组中,每碰到一个叶节点就输出从根节点到该叶节点的路径,即该叶节点的最优前缀码。 构造前缀码过程中,Ht[i].weight用做被遍历节点的遍历状态:为0表示节点i未被遍历过; 1表示已经被遍历过;2表示位于i节点的分支都被遍历,下步该遍历i节点的兄弟节点分支。故while语句下的3个if语句很明显分别对应这3种情况。 第一个if语句中,如果i节点没有被遍历过(Ht[i].weight为0),则应该先考查其是否有左子节点,有的话就表示其还不是叶节点,则下一个被遍历的节点为其左节点,同时将“0”字符保存到code数组中。如果没有左节点且没有右节点,表示其为叶节点,保存该路径。空 (1)之后的strcpy就是实现字符串拷贝,而字符串结束标志是“/0”,因此空(1)应填“code[cdlen]='/0'”。这点在实际编程时亦需要特别注意。 第二个if语句中,考查Ht[i].weight等于1的情况,如果成立则表示i节点被遍历过(即已考查了其左节点),如果该节点没有右节点(Ht[i].rchild为0),应该回退到它的父节点,求下一个叶节点的编码;否则,记录字符“1”,继续遍历其右子树。 第三个if语句为回退到父节点,即指针p应指向i节点的父节点,同时路径存储数组code也应该回退一个字符(特别注意这一点)。故空(2)应填“Ht[i].parent”,空(3)应填“--cdlen”。 函数Decode的功能是将前缀码序列翻译成叶子节点的字符序列并输出。根据前缀编码在 Huffman树中表示的意义,程序依次扫描前缀码序列,根据扫描到的编码值遍历Huffman树:为0往左子树继续扫描,为1往右子树扫描。据注释,空(4)是进入左子树的条件,应该为“*buff==0”。 空(5)有比较大的难度。仔细分析while循环,会发现当while循环结束时,buff已经指向下一个叶子节点编码的第二个字符了。故空(5)应将编码字符指针回退一个字符,即应填“buff--”。