数据结构 C语言版 第二版(严蔚敏) 第章 树和二叉树 答案

发布时间:2020-01-05 09:19:15

5 树和二叉树

1.选择题

1把一棵树转换为二叉树后,这棵二叉树的形态是 )。

A唯一的 有多种

C有多种,但根结点都没有左孩子 有多种,但根结点都没有右孩子

答案:A

解释:因为二叉树有左孩子、右孩子之分,故一棵树转换为二叉树后,这棵二叉树的形态是唯一的。

23个结点可以构造出多少种不同的二叉树?(

A2 B3 C4 D5

答案:D

解释:五种情况如下:

word/media/image1.gif word/media/image3.gif word/media/image4.gif word/media/image5.gif word/media/image6.gif

3一棵完全二叉树上有1001个结点,其中叶子结点的个数是

A250 B 500 C254 D501

答案:D

解释:设度为0结点(叶子结点)个数为A,度为1的结点个数为B,度为2的结点个数为C,有A=C+1A+B+C=1001,可得2C+B=1000,由完全二叉树的性质可得B=01,又因为C为整数,所以B=0C=500A=501,即有501个叶子结点。

4一个具有1025个结点的二叉树的高h为(

A11 B10 C111025之间 D101024之间

答案:C

解释:若每层仅有一个结点,则树高h1025;且其最小树高为 log21025 + 1=11,即h111025之间。

5深度为h的满m叉树的第k层有( )个结点。(1=

Amk-1 Bmk-1 Cmh-1 Dmh-1

答案:A

解释:深度为h的满m叉树共有mh-1个结点,第k层有mk-1个结点。

6利用二叉链表存储树,则根结点的右指针是(

A.指向最左孩子 B.指向最右孩子 C.空 D.非空

答案:C

解释:利用二叉链表存储树时,右指针指向兄弟结点,因为根节点没有兄弟结点,故根节点的右指针指向空。

7对二叉树的结点从1开始进行连续编号,要求每个结点的编号大于其左、右孩子的编号,同一结点的左右孩子中,其左孩子的编号小于其右孩子的编号,可采用( )遍历实现编号。

A.先序 B. 中序 C. 后序 D. 从根开始按层次遍历

答案:C

解释:根据题意可知按照先左孩子、再右孩子、最后双亲结点的顺序遍历二叉树,即后序遍历二叉树。

8若二叉树采用二叉链表存储结构,要交换其所有分支结点左、右子树的位置,利用( )遍历方法最合适。

A.前序 B.中序 C.后序 D.按层次

答案:C

解释:后续遍历和层次遍历均可实现左右子树的交换,不过层次遍历的实现消耗比后续大,后序遍历方法最合适。

9在下列存储形式中,( )不是树的存储形式?

A.双亲表示法 B.孩子链表表示法 C.孩子兄弟表示法 D.顺序存储表示

答案:D

解释:树的存储结构有三种:双亲表示法、孩子表示法、孩子兄弟表示法,其中孩子兄弟表示法是常用的表示法,任意一棵树都能通过孩子兄弟表示法转换为二叉树进行存储。

10一棵非空的二叉树的先序遍历序列与后序遍历序列正好相反,则该二叉树一定满足(

A.所有的结点均无左孩子 B.所有的结点均无右孩子

C.只有一个叶子结点 D.是任意一棵二叉树

答案:C

解释:因为先序遍历结果是“中左右”,后序遍历结果是“左右中”,当没有左子树时,就是“中右”和“右中”;当没有右子树时,就是“中左”和“左中”。则所有的结点均无左孩子或所有的结点均无右孩子均可,所以AB不能选,又所有的结点均无左孩子所有的结点均无右孩子时,均只有一个叶子结点,故选C

11)设哈夫曼树中有199个结点,则该哈夫曼树中有( )个叶子结点。

A99 B100

C101 D102

答案:B

解释:在哈夫曼树中没有度为1的结点,只有度为0(叶子结点)度为2结点设叶子结点的个数为n0,度为2的结点的个数为n2由二叉树的性质n0=n2+1,则总结点数n= n0+n2=2*n0-1,得到n0=100

12X是二叉中序线索树中一个有左孩子的结点,且X不为根,则X的前驱为(

AX的双亲 BX的右子树中最左的结点

CX的左子树中最右结点 DX的左子树中最右叶结点

答案:C

13引入二叉线索树的目的是

A.加快查找结点的前驱或后继的速度 B.为了能在二叉树中方便的进行插入与删除

C.为了能方便的找到双亲 D.使二叉树的遍历结果唯一

答案:A

14)设F是一个森林,B是由F变换得的二叉树。若F中有n个非终端结点,则B中右指针域为空的结点有( )个。

An1 Bn Cn + 1 Dn + 2

答案:C

15nn2)个权值均不相同的字符构成哈夫曼树,关于该树的叙述中,错误的是( )。

A.该树一定是一棵完全二叉树

B.树中一定没有度为1的结点

C.树中两个权值最小的结点一定是兄弟结点

D.树中任一非叶结点的权值一定不小于下一层任一结点的权值

答案:A

解释:哈夫曼树的构造过程是每次都选取权值最小的树作为左右子树构造一棵新的二叉树,所以树中一定没有度为1的结点、两个权值最小的结点一定是兄弟结点、任一非叶结点的权值一定不小于下一层任一结点的权值。

2.应用

1试找出满足下列条件的二叉树

word/media/image7.gif先序序列与后序序列相同 word/media/image8.gif中序序列与后序序列相同

word/media/image9.gif先序序列与中序序列相同 word/media/image10.gif中序序列与层次遍历序列相同

答案:先序遍历二叉树的顺序是“根左子树右子树”,中序遍历“左子树右子树”,后序遍历顺序是:“左子树右子树―根",根据以上原则有

word/media/image11.gif或为空树,或为只有根结点的二叉树

word/media/image12.gif  或为空树,或为任一结点至多只有左子树的二叉树.

word/media/image13.gif  或为空树,或为任一结点至多只有右子树的二叉树.

word/media/image14.gif或为空树,或为任一结点至多只有右子树的二叉树

2设一棵二叉树的先序序列: A B D F C E G H ,中序序列: B F D A G E H C

word/media/image7.gif画出这棵二叉树。

word/media/image8.gif画出这棵二叉树的后序线索树。

word/media/image9.gif将这棵二叉树转换成对应的树(或森林)。

答案:

word/media/image15.gif

 

 

 

 

 

 

 

 

word/media/image11.gif word/media/image12.gif

3 假设用于通信的电文仅由8个字母组成,字母在电文中出现的频率分别为0.070.190.020.060.320.030.210.10

word/media/image7.gif试为这8个字母设计夫曼编码。

word/media/image8.gif试设计另一种二进制表示等长编码方案。

word/media/image9.gif对于上述实例,比较两种方案的优缺点。

答案:方案1;哈夫曼编码

先将概率放大100倍,以方便构造哈夫曼树。

w={7,19,2,6,32,3,21,10},按哈夫曼规则:【[2,3),6], (7,10), ……19, 21, 32

word/media/image16.gif100

40 60

word/media/image17.gif19 21 32 28

word/media/image18.gif17 11

7 10 6 5

2 3

word/media/image20.gif

方案比较:

word/media/image21.gif

方案1WPL2(0.19+0.32+0.21)+4(0.07+0.06+0.10)+5(0.02+0.03)=1.44+0.92+0.25=2.61

方案2WPL3(0.19+0.32+0.21+0.07+0.06+0.10+0.02+0.03)=3

结论:哈夫曼编码优于等长二进制编码

 4已知下列字符ABCDEFG的权值分别为312742811,试填写出其对应哈夫曼树HT的存储结构的初态和终态。

答案:

初态:

 

终态:

3.算法设计

以二叉链表作为二叉树的存储结构,编写以下算法:

1)统计二叉树的叶结点个数

[题目分析]如果二叉树为空,返回0,如果二叉树不为空且左右子树为空,返回1,如果二叉树不为空,且左右子树不同时为空,返回左子树中叶子节点个数加上右子树中叶子节点个数

[算法描述]

int LeafNodeCount(BiTree T)

{

if(T==NULL)

return 0; //如果是空树,则叶子结点个数为0

else if(T->lchild==NULL&&T->rchild==NULL)

return 1; //判断结点是否是叶子结点(左孩子右孩子都为空),若是则返回1

else

return LeafNodeCount(T->lchild)+LeafNodeCount(T->rchild);

}

2)判别两棵树是否相等

[题目分析]先判断当前节点是否相等(需要处理为空、是否都为空、是否相等),如果当前节点不相等,直接返回两棵树不相等;如果当前节点相等,那么就递归的判断他们的左右孩子是否相等。

[算法描述]

int compareTree(TreeNode* tree1, TreeNode* tree2)

//用分治的方法做,比较当前根,然后比较左子树和右子树

{bool tree1IsNull = (tree1==NULL);

bool tree2IsNull = (tree2==NULL);

if(tree1IsNull != tree2IsNull)

{

return 1;

}

if(tree1IsNull && tree2IsNull)

{//如果两个都是NULL,则相等

return 0;

}//如果根节点不相等,直接返回不相等,否则的话,看看他们孩子相等不相等

if(tree1->c != tree2->c)

{

 return 1;

}

return (compareTree(tree1->left,tree2->left)&compareTree(tree1->right,tree2->right))

(compareTree(tree1->left,tree2->right)&compareTree(tree1->right,tree2->left));

}//算法结束

3交换二叉树每个结点的左孩子和右孩子。

[题目分析]如果某结点左右子树为空,返回,否则交换该结点左右孩子,然后递归交换左右子树。

[算法描述]

void ChangeLR(BiTree &T)

{

BiTree temp;

if(T->lchild==NULL&&T->rchild==NULL)

return;

else

{

temp = T->lchild;

T->lchild = T->rchild;

T->rchild = temp;

}//交换左右孩子

ChangeLR(T->lchild); //递归交换左子树

ChangeLR(T->rchild); //递归交换右子树

}

4设计二叉树的双序遍历算法(双序遍历是指对于二叉树的每一个结点来说,先访问这个结点,再按双序遍历它的左子树,然后再一次访问这个结点,接下来按双序遍历它的右子树)

[题目分析]若树为空,返回;若某结点为叶子结点,则仅输出该结点;否则先输出该结点,递归遍历其左子树,再输出该结点,递归遍历其右子树。

[算法描述]

void DoubleTraverse(BiTree T)

{

if(T == NULL)

return;

else if(T->lchild==NULL&&T->rchild==NULL)

cout<data; //叶子结点输出

数据结构 C语言版 第二版(严蔚敏) 第章 树和二叉树 答案

相关推荐