第六章树和二叉树习题数据结构.docx
《第六章树和二叉树习题数据结构.docx》由会员分享,可在线阅读,更多相关《第六章树和二叉树习题数据结构.docx(21页珍藏版)》请在冰点文库上搜索。
第六章树和二叉树习题数据结构
习题六树和二叉树
、单项选择题
1.以下说法错误的是()
A.树形结构的特点是一个结点可以有多个直接前趋
B.线性结构中的一个结点至多只有一个直接后继
C.树形结构可以表达(组织)更复杂的数据
D.树(及一切树形结构)是一种“分支层次“结构
E.任何只含一个结点的集合是一棵树
2.下列说法中正确的是()
A.任何一棵二叉树中至少有一个结点的度为2
B.任何一棵二叉树中每个结点的度都为2
C.任何一棵二叉树中的度肯定等于2
D.任何一棵二叉树中的度可以小于2
3.讨论树、森林和二叉树的关系,目的是为了(
A.借助二叉树上的运算方法去实现对树的一些运算
B.将树、森林按二叉树的存储方式进行存储
C.将树、森林转换成二叉树
D体现一种技巧,没有什么实际意义
4
无序数据元素元素之间无联系的数据
树最适合用来表示()
A有序数据元素B
C元素之间具有分支层次关系的数据D
5若一棵二叉树具有
10个度为2的结点,
5个度为1的结点,则度为
0的结点个数是(
11C15D不确定
6.设森林F中有三棵树,第一,第二,第三棵树的结点个数分别为M1,M2和M3。
与森林
结点的右子树上的结点个数是()。
)
F对应的二叉树根
M1+M2C.M3D.M2+M3
1001个结点,其中叶子结点的个数是()
.以上答案都不对
8.设给定权值总数有n
A不确定
9二叉树的第I层上最多含有结点数为(A2IB2I-1-1C
一棵二叉树高度为h,所有结点的度或为
10.
个,其哈夫曼树的结点总数为
.2nC.2n+1
)
.2n-1
0,
)
2I-1
,或为2,
A.2hB.2h-1C.2h+1
利用二叉链表存储树,则根结点的右指针是(
A.指向最左孩子B.指向最右孩子
在二叉树结点的先序序列,中序序列和后序序列中,A.都不相同B
C.先序和中序相同,而与后序不同D
15在完全二叉树中,若一个结点是叶结点,则它没(
A左子结点B
C左子结点和右子结点D
16在下列情况中,可称为二叉树的是(
11.
14.
.右子结点
.左子结点,
)
D.2I-1
则这棵二叉树最少有()
.h+1
)。
C空D非空
所有叶子结点的先后顺序(
完全相同
中序和后序相同,而与先序不同
)。
右子结点和兄弟结点
结点
A.每个结点至多有两棵子树的树
B.哈夫曼树
C.每个结点至多有两棵子树的有序树
D.每个结点只有一棵右子树
E.以上答案都不对
17.
一棵左右子树均不空的二叉树在先序线索化后,其中空的链域的个数是:
()
21.下面几个符号串编码集合中,不是前缀编码的是()。
A.{0,10,110,1111}B.{11,10,001,101,0001}
C.{00,010,0110,1000}D.{b,c,aa,ac,aba,abb,abc}
22.一棵有n个结点的二叉树,按层次从上到下,同一层从左到右顺序存储在一维数组A[1..n]中,则二叉树
中第i个结点(i从1开始用上述方法编号)的右孩子在数组A中的位置是()
A.A[2i](2i<=n)B.A[2i+1](2i+1<=n)
C.A[i-2]D.条件不充分,无法确定
23、以下说法错误的是()
A.哈夫曼树是带权路径长度最短的树,路径上权值较大的结点离根较近。
B.若一个二叉树的树叶是某子树的中序遍历序列中的第一个结点,则它必是该子树的后序遍历序列中的第一个结点。
C.已知二叉树的前序遍历和后序遍历序列并不能惟一地确定这棵树,因为不知道树的根结点是哪一个。
D.在前序遍历二叉树的序列中,任何结点的子树的所有结点都是直接跟在该结点的之后。
二、判断题(在各题后填写“/或“X”)
1.完全二叉树一定存在度为1的结点。
()
2.对于有N个结点的二叉树,其高度为log2n。
()
3.二叉树的遍历只是为了在应用中找到一种线性次序。
()
4.
一棵一般树的结点的前序遍历和后序遍历分别与它相应二叉树的结点前序遍历和后序遍历是一致的
1.在二叉树中,指针p所指结点为叶子结点的条件是。
2.深度为k的完全二叉树至少有个结点,至多有个结点
3•高度为8的完全二叉树至少有______个叶子结点。
4.具有n个结点的二叉树中,一共有个指针域,其中只有个用来指向结点的左右孩子,
其余的个指针域为NULL
5.树的主要遍历方法有、、等三种。
6.—个深度为k的,具有最少结点数的完全二叉树按层次,(同层次从左到右)用自然数依此对结点编号,
则编号最小的叶子的序号是—_;编号是i的结点所在的层次号是__(根所在的层次
号规定为1层)。
7•如果结点A有3个兄弟,而且B是A的双亲,贝UB的度是______o
8.二叉树的先序序列和中序序列相同的条件是__o
9.一个无序序列可以通过构造一棵____树而变成一个有序序列,构造树的过程即为对无序序列进行
排序的过程。
10•若一个二叉树的叶子结点是某子树的中序遍历序列中的最后一个结点,则它必是该子树的_—
序列中的最后一个结点。
11•若以{4,5,6,7,8}作为叶子结点的权值构造哈夫曼树,则其带权路径长度是______o
12•以下程序段采用先根遍历方法求二叉树的叶子数,请在横线处填充适当的语句。
Voidcountleaf(bitreptrt,int*count)/*根指针为t,假定叶子数count的初值为0*/
{if(t!
=NULL)
{if((t->lchild==NULL)&&(t->rchild==NULL));
countleaf(t->lchild,&count);
}
}
请填空使之完善。
二叉树链表的结点类型的定义如下:
为根结点的指针*/初始化栈s为空栈*/栈s不为空*/
入栈*/
13•以下程序是二叉链表树中序遍历的非递归算法,
typedefstructnode/*C语言/
{chardata;structnode*lchild,*rchild;}*bitree;
voidvst(bitreebt)/*bt
{bitreep;p=bt;initstack(s);/*
while(p||!
empty(s))/*
if(p){push(s,p);
(1)___;}/*P
else{p=pop(s);printf(“%c,p->data);
(2)•工栈顶元素岀栈*/
}
14•二叉树存储结构同上题,以下程序为求二叉树深度的递归算法,请填空完善之。
intdepth(bitreebt)/*bt为根结点的指针*/
{inthl,hr;
if(bt==NULL)return(
(1)_);
hl=depth(bt->lchild);hr=depth(bt->rchild);
if(⑵)_(3;
return(hr+1);
}
15•将二叉树bt中每一个结点的左右子树互换的C语言算法如下,其中ADDQ(Q,bt),DELQ(Q),EMPTY(Q)分别
为进队,岀队和判别队列是否为空的函数,请填写算法中得空白处,完成其功能。
typedefstructnode
{intdata;structnode*lchild,*rchild;}btnode;voidEXCHANGE(btnode*bt)
{btnode*p,*q;
if(bt){ADDQ(Q,bt);
while(!
EMPTY(Q))
{p=DELQ(Q);q=
(1)___;p->rchild=
(2)___;⑶=q;
if(p->lchild)(4)___;if(p->rchild)(5)___;
}
}}〃
四、应用题
1•树和二叉树之间有什么样的区别与联系?
2.分别画出具有3个结点的树和3个结点的二叉树的所有不同形态。
3•分别给岀下图所示二叉树的先根、中根和后根序列。
4•一个深度为L的满K叉树有以下性质:
第L层上的结点都是叶子结点,其余各层上每个结点都有K棵
非空子树,如果按层次顺序从1开始对全部结点进行编号,求:
1)各层的结点的数目是多少?
2)编号为n的结点的双亲结点(若存在)的编号是多少?
3)编号为n的结点的第i个孩子结点(若存在)的编号是多少?
4)编号为n的结点有右兄弟的条件是什么?
如果有,其右兄弟的编号是多少?
请给岀计算和推导过程。
5•将下列由三棵树组成的森林转换为二叉树。
(只要求给岀转换结果)
(l)画岀二叉树BT的逻辑结构
(3)画出二叉树的后序线索树。
五、算法设计题
1•要求二叉树按二叉链表形式存储,
(1)写一个建立二叉树的算法。
(2)写一个判别给定的二叉树是否是完全二叉树的算法。
完全二叉树定义为:
深度为K,具有N个结点的二叉树的每个结点都与深度为K的满二叉树中编号从1至
N的结点一一对应。
此题以此定义为准。
2•设一棵二叉树的结点结构为(LLINK,INFO,RLINK),ROOT为指向该二叉树根结点的指针,p和q分别为指向该二叉树中任意两个结点的指针,试编写一算法ANCESTORROOTp,q,r),该算法找到p和q的最近共同祖
先结点r。
3•有一二叉链表,试编写按层次顺序遍历二叉树的算法。
4•已知二叉树按照二叉链表方式存储,利用栈的基本操作写出先序遍历非递归形式的算法。
5.对于二叉树的链接实现,完成非递归的中序遍历过程。
6•试写出复制一棵二叉树的算法。
二叉树采用标准链接结构。
。
7•请设计一个算法,要求该算法把二叉树的叶子结点按从左到右的顺序连成一个单链表,表头指针为head。
二叉树按二叉链表方式存储,链接时用叶子结点的右指针域来存放单链表指针。
分析你的算法的时、空复杂度。
8•已知二叉树以二叉链表存储,编写算法完成:
对于树中每一个元素值为x的结点,删去以它为根的子树,
并释放相应的空间。
9.设一棵二叉树的根结点指针为T,C为计数变量,初值为0,试写出对此二叉树中结点计数的算法:
BTLC
(T,C)。
10.分别写出算法,实现在中序线索二叉树T中查找给定结点*p在中序序列中的前驱与后继。
在先序线
索二叉树T中,查找给定结点*p在先序序列中的后继。
在后序线索二叉树T中,查找给定结点*p在后序序列中的前驱。
第六章树和二叉树
一、单项选择题
1.A
2.D
3.A
4.C
5.B
6.D
7.E
8.D
9.C
10.B
11.C
12.A
13.D
14.B
15.C
16.B
17.B
18.A
19.C
20.D
21.B
22.D
23.C
二、判断题(在各题后填写“/或“X”)
1.完全二叉树一定存在度为1的结点。
X
2.对于有N个结点的二叉树,其高度为log2n。
X
3.二叉树的遍历只是为了在应用中找到一种线性次序。
V
4.一棵一般树的结点的前序遍历和后序遍历分别与它相应二叉树的结点前序遍历和后序遍历是一致的。
5.用一维数组存储二叉树时,总是以前序遍历顺序存储结点。
X
6.中序遍历一棵二叉排序树的结点就可得到排好序的结点序列V
7.完全二叉树中,若一个结点没有左孩子,则它必是树叶。
V
8.二叉树只能用二叉链表表示。
X
9.给定一棵树,可以找到唯一的一棵二叉树与之对应。
V
10.用链表(llink-rlink)存储包含n个结点的二叉树,结点的2n个指针区域中有n-1个空指针。
X
11.树形结构中元素之间存在一个对多个的关系。
V
12.将一棵树转成二叉树,根结点没有左子树。
X
13.度为二的树就是二叉树。
X
14.二叉树中序线索化后,不存在空指针域。
X
15.霍夫曼树的结点个数不能是偶数。
V
16.哈夫曼树是带权路径长度最短的树,路径上权值较大的结点离根较近。
V
三、填空题
1.p->lchild==null&&p->rchlid==null
2.
(1)2k-1
(2)2k-1
3.64
4.
2nn-1n+1
6..
(1)2k-2+1(第k层1个结点,总结点个数是2H-1,其双亲是2H-1/2=2k-2)
(2)Iog2i+1
7.4
8•任何结点至多只有右子女的二叉树。
9.二叉排序树
10•前序
11.69
12.*count++,countleaf(l->rchile,count)
13.
(1)p=p->lchild//沿左子树向下
(2)p=p->rchild
14.
(1)0
(2)hl>hr(3)hr=hl
15.
(1)p->rchild
(2)p->lchild(3)p->lchild
(4)ADDQ(Q,p->lchild)(5)ADDQ(Q,p->rchild)
四、应用题
1•树和二叉树逻辑上都是树形结构,树和二叉树的区别有三:
一是二叉树的度至多为2,树无此限制;二是
二叉树有左右子树之分,即使在只有一个分枝的情况下,也必须指岀是左子树还是右子树,树无此限制;三
是二叉树允许为空,树一般不允许为空(个别书上允许为空)。
二叉树不是树的特例。
2.【解答】
具有3个结点的树具有3个结点的二叉树
3•解答:
先根序列:
ABCDEFGHIJ;
中根序列:
BCDAFEHJIG;
后根序列:
DCBFJIHGEA。
4.
(1)kh-1(h为层数)
(2)因为该树每层上均有KT个结点,从根开始编号为1,则结点i的从右向左数第2个孩子的结点编号为
ki。
设n为结点i的子女,则关系式(i-1)k+2<=n<=ik+1成立,因i是整数,故结点n的双亲i的编号为
n-2)/k+1。
(3)结点n(n>1)的前一结点编号为n-1(其最右边子女编号是(n-1)*k+1),故结点n的第i个孩子的编
号是(n-1)*k+1+i。
(4)根据以上分析,结点n有右兄弟的条件是,它不是双亲的从右数的第一子女,即(n-1)%k!
=0,其右兄
弟编号是n+1。
5.
6.
(
其哈夫曼编码如下A:
1,B:
000,C:
01,D:
001
五、.
1.[芸建立最简单。
判定是否是完全二叉树,可以使用队列,在遍
历中;•右子女”的原则进行判断。
{ElemTypex;BiTreebt;scanf(“%d,&x);1//if(x==0)bt=null;
elseif(x>0)
sizeof(BiNode));
{bt=(BiNode*)malloc(
bt->data=x;bt->lchild=creat();bt->rchild=creat();}
elseerror(“输入错误”);
return(bt);
}//结束BiTree
intJudgeComplete(BiTreebt)//判断二叉树是否是完全二叉树,如是,返回1,否则,返回0
if(p==null)return
(1);QueueInit(Q);QueueIn(Q,p);//
while(!
QueueEmpty(Q))
{p=QueueOut(Q);//
if(p->lchild&&!
tag)QueueIn(Q,p->lchild);//
else{if(p->lchild)return0;//elsetag=1;//
if(p->rchild&&!
tag)QueueIn(Q,p->rchild);//
elseif(p->rchild)return0;elsetag=1;
}//while
return1;}//JudgeComplete
[算法讨论]完全二叉树证明还有其它方法。
判断时易犯的错误是证明其左子树和右子数都是完全二叉树,由此推出整棵二叉树必是完全二叉树的错误结论。
2.[题目分析]后序遍历最后访问根结点,即在递归算法中,根是压在栈底的。
采用后序非递归算法,栈中存放二叉树结点的指针,当访问到某结点时,栈中所有元素均为该结点的祖先。
本题要找p和q的最近共同祖先结点r,不失一般性,设p在q的左边。
后序遍历必然先遍历到结点p,栈中元素均为p的祖先。
将栈拷入另
一辅助栈中。
再继续遍历到结点q时,将栈中元素从栈顶开始逐个到辅助栈中去匹配,第一个匹配(即相等)
的元素就是结点p和q的最近公共祖先。
typedefstruct
{BiTreet;inttag;//tag=0表示结点的左子女已被访问,tag=1表示结点的右子女已被访问
}stack;
stacks[],s1[];//栈,容量够大
BiTreeAncestor(BiTreeROOT,p,q,r)//求二叉树上结点p和q的最近的共同祖先结点r。
{top=0;bt=ROOT;
while(bt!
=null||top>0)
{while(bt!
=null&&bt!
=p&&bt!
=q)//结点入栈
{s[++top].t=bt;s[top].tag=0;bt=bt->lchild;}//沿左分枝向下
if(bt==p)//不失一般性,假定p在q的左侧,遇结点p时,栈中元素均为p的祖先结点{for(i=1;i<=top;i++)s1[i]=s[i];top1=top;}//将栈s的元素转入辅助栈s1保存
if(bt==q)//找到q结点。
for(i=top;i>0;i--)//;将栈中元素的树结点到s1去匹配
{pp=s[i].t;
for(j=top1;j>0;j--)
if(s1[j].t==pp){printf(“p和q的最近共同的祖先已找到”);return(pp);}
}
while(top!
=0&&s[top].tag==1)top--;//退栈
if(top!
=0){s[top].tag=1;bt=s[top].t->rchild;}//沿右分枝向下遍历
}//结束while(bt!
=null||top>0)return(null);〃q、p无公共祖先
退栈,访问,转右子树
if(top>0){p=s[top--];printf(p->data);p=p->rchild;}//
}}
6.BiTreeCopy(BiTreet)//复制二叉树t
{BiTreebt;
if(t==null)bt=null;
else{bt=(BiTree)malloc(sizeof(BiNode));bt->data=t->data;bt->lchild=Copy(t->lchild);
bt->rchild=Copy(t->rchild);
}
return(bt);}//结束Copy
7.[题目分析]叶子结点只有在遍历中才能知道,这里使用中序递归遍历。
设置前驱结点指针pre,初始为空第一个叶子结点由指针head指向,遍历到叶子结点时,就将它前驱的rchild指针指向它,最后叶子结点的rchild为空。
LinkedListhead,pre=null;//全局变量
LinkedListInOrder(BiTreebt)
//中序遍历二叉树bt,将叶子结点从左到右链成一个单链表,表头指针为head
叶子结点处理第一个叶子结点将叶子结点链入链表中序遍历左子树设置链表尾
{if(bt){InOrder(bt->lchild);//中序遍历左子树
if(bt->lchild==null&&bt->rchild==null)//if(pre==null){head=bt;pre=bt;}//else{pre->rchild=bt;pre=bt;}//InOrder(bt->rchild);//pre->rchild=null;//
}return(head);}//InOrder时间复杂度为O(n),辅助变量使用head和pre,栈空间复杂度O(n)
8.[题目分析]删除以元素值x为根的子树,只要能删除其左右子树,就可以释放值为x的根结点,因此宜采用后序遍历。
删除值为x结点,意味着应将其父结点的左(右)子女指针置空,用层次遍历易于找到某结点的父结点。
本题要求删除树中每一个元素值为x的结点的子树,因此要遍历完整棵二叉树。
voidDeleteXTree(BiTreebt)//删除以bt为根的子树
删除bt的左子树、右子树
释放被删结点所占的存储空间
{DeleteXTree(bt->lchild);DeleteXTree(bt->rchild);//free(bt);}//DeleteXTree//
voidSearch(B:
Treebt,ElemTypex)
//在二叉树上查找所有以x为元素值的结点,并删除以其为根的子树{BiTreeQ[];//Q是存放二叉树结点指针的队列,容量足够大
if(bt)
{if(bt->data==x){DeleteXTree(bt);exit(0);}//{QueueInit(Q);QueueIn(Q,bt);
while(!
QueueEmpty(Q)){p=QueueOut(Q);
if(p->lchild)//
if(p->lchild->data==x)//
若根结点的值为x,则删除整棵树
若左子女非空
左子女结点值为
{DeleteXTree(p->lchild);p->lchild=null;}//elseEnqueue(Q,p->lchild);//if(p->rchild)//if(p->rchild->data==x)//{DeleteXTree(p->rchild);p->rchild=null;}//
x,应删除当前结点的左子树
父结点的左子女置空
左子女入队列
若右子女非空
右子女结点值为
x,应删除当前结点的右子树父结点的右子女置空
elseEnqueue(Q,p->rchild);//右子女入队列
}//while
}//if(bt)}//search
9.intBTLC(BiTreeT,int*c)〃对二叉树T的结点计数
{if(T)
{*c++;
BT