一个结点的子结点个数为该结点的C。
供选择的答案
A:
①有0个或1个②有0个或多个③有
且只有1个④有1个或1个以上
B:
①互不相交②允许相交
③允许
叶结点相交
④允许树枝结点相交
C:
①权
②维数
③次数
(或度)
④序
答案:
ABC=
1,1,3
6.【95程P13】从供选择的答案中,选出应填入下面叙述?
内的最确切的解答,把相应编号写在答卷的对应栏内。
二叉树丄。
在完全的二叉树中,若一个结点没有B—,则它必定是叶结点。
每棵树都能惟一地转换成与它对应的二叉树。
由树转换成的二叉树里,一个结点N
的左子女是N在原树里对应结点的C,而N的右子女是它在原树里对应结点的_D。
供选择的答案
A:
①是特殊的树②不是树的特殊形式③是两棵
树的总称④有是只有二个根结点的树形结构
B:
①左子结点②右子结点③左子结点或者没
有右子结点④兄弟
C〜D:
①最左子结点
②最右子结点
③
最邻近的右兄弟④
最邻近的左兄弟
⑤最左的兄弟
⑥最右的兄弟
答案:
A=B=
C=
D=
答案:
ABCDE=2,1,1,3
四、简答题(每小题4分,共20分)
1.[严题集6.2①】一棵度为2的树与一棵二叉树有何区另U?
答:
度为2的树从形式上看与二叉树很相似,但它的子树是无序的,而二叉树是有序的。
即,在一般树中若某结点只有一个孩子,就无需区分其左右次序,而在二叉树中即使是一个孩子也有左右之分。
2.
C的结点类型定义如下:
structnode
{chardata;
structnode*lchild,
rchild;
〖01年计算机研题〗设如下图所示的二叉树B的存储结构为二叉链表,root为根指针,结点结构为:
(lchild,data,rchild)。
其中Ichild,rchild分别为指向左右孩子的指针,data为字符型,root为根指针,试
10
回答下列问题:
1.对下列二叉树B,执行下列算法traversal(root),试指出其输出结果;
2.假定二叉树B共有n个结点,试分析算法traversal(root)的时间复杂度。
(共8分)
/、A
//、
、B
二叉树B解:
这是“先根再左再根再右”,比前序遍历多打印各结点一次,输出结果为:
ABCCEEBADFFDGG特点:
①每个结点肯定都会被打印两次;②但出现的顺序不同,其规律是:
凡是有左子树的结点,必间隔左子树的全部结点后再重复出现;如A,B,D等结点。
反之马上就会重复出现。
如C,E,F,G等结点。
时间复杂度以访问结点的次数为主,精确值为2*n,时
间渐近度为0(n).
3.〖01年计算机研题〗【严题集6.27③】给定二叉树的两种遍历序列,分别是:
前序遍历序列:
D,A,C,E,B,H,F,G,I;中序遍历序列:
D,C,B,E,H,A,G,I,F,试画出二叉树B,并简述由任意二叉树B的前序遍历序
11
列和中序遍历序列求二叉树B的思想方法。
解:
方法是:
由前序先确定root,由中序可确定root的左、右子树。
然后由其左子树的元素集合和右子树的集合对应前序遍历序列中的元素集合,可继续确定root的左右孩子。
将他们分别作为新的root,不断递归,则所有元素都将被唯一确定,问题得解。
55
12
五、阅读分析题(每题5分,共20分)
1.(P604-26)试写出如图所示的二叉树分别按先序、
中序、后序遍历时得到的结点序列。
答:
DLR:
LDR:
ABDFJGKCEHILM.「
BFJDGKACHELIM‘
JKLif
LRD:
JFKGDBHLMIECA
2.(P604-27)把如图所示的树转化成二叉树
答:
注意全部兄弟之间都要连线(包括度为2的兄弟),并注意原有连线结点一律归入左子树,新添连
13
L、GI
MJ
4.【严题集6.21②】画出和下列二叉树相应的森林。
答
:
注意根右边的子树肯定是森林,
而
孩子结点的右子树均为兄弟
14
六、算法设计题(前5题中任选2题,第6题必做,每题8分,共24分)
1.【严题集6.42③】编写递归算法,计算二叉树中叶子结点的数目。
解:
思路:
输出叶子结点比较简单,用任何一种遍历递归算法,凡是左右指针均空者,则为叶子,将其打印出来。
法一:
核心部分为:
DLR(liuyu*root)/*中序遍历递归函数*/
{if(root!
=NULL)
{if((root->lchild==NULL)&&(root->rchild==NULL)){sum++;printf("%d\n",root->data);}
DLR(root->lchild);
DLR(root->rchild);}
return(0);
}
法二:
intLeafCount_BiTree(BitreeT)〃求二叉树中叶子结点的数目
{
if(!
T)return0;//空树没有叶子
elseif(!
T->lchild&&!
T->rchild)return1;//叶子结点elsereturn
15
Leaf_Count(T->lchild)+Leaf_Count(T->rchild);〃左子树
的叶子数加
上右子树的叶子数
}//LeafCount_BiTree
注:
上机时要先建树!
例如实验二的方案一。
①打印叶子结点值(并求总数)
思路:
先建树,再从遍历过程中打印结点值并统计。
步骤1键盘输入序列12,8,17,11,16,2,13,9,
21,4,构成一棵二叉排序树。
叶子结点值应该是4,9,13,21,总数应该是4.
八/'八12
7仃
2111621
4913
编程:
生成二叉树排序树之后,再中序遍历排序查找结点的完整程序如下:
说明部分为:
#includevstdio.h>
data;structliuyu
#includevstdlib・h>
typedefstructliuyu{int*lchild,*rchild;}test;
16
liuyu*root;
intsum=0;intm=sizeof(test);
voidinsert_data(intx)/*如何生成二叉排序
树?
参见教材P43C程序*/
{liuyu*p,*q,*s;
s=(test*)malloc(m);
s->data=x;s->lchild=NULL;s->rchild=NULL;
if(!
root){root=s;return;}
p=root;
while(p)/*如何接入二叉排序树的适
当位置*/
{q=p;
if(p->data==x){printf("dataalreadyexist!
\n");return;}elseif(xdata)p=p->lchild;elsep=p->rchild;
}
if(xdata)q->lchild=s;
elseq->rchild=s;
}
17
DLR(liuyu*root)/*中序遍历递归函数*/
{if(root!
=NULL)
{if((root->lchild==NULL)&&(root->rchild==NULL)){sum++;printf("%d\n",root->data);}
DLR(root->lchild);
DLR(root->rchild);}
return(0);
}
main()I*先生成二叉排序树,再调用中序
遍历递归函数进行排序输出*1
{inti,x;
i=1;
root=NULL;I*千万别忘了赋初值给
root!
*/do{printf("pleaseinputdata%d:
",i);
i++;
scanf("%d",&x);I*从键盘采集数据,以
-9999表示输入结束*/
if(x==-9999){
DLR(root);
printf("\nNowoutputcountvalue:
%d\n",sum);return(0);}
18
/*调用插入数据元
elseinsert_data(x);}素的函数*/
while(x!
=-9999);return(0);}
IIK(inactivex)
|n|x]
pl直砒pinputdatal
12
▲
input
S
pleaseinputdata3
17
&inputdata4
11
inputdates
16
inputdata&
2
pleaseinputdata7
13
inputdataG
9
pleaseinputdata9
21
pleaseinputdatal0:
H
pl»as»i叩utdatal1:
-9999
4
9
13
21
Nchoutputcountualu«:
执行结果:
若一开始运行就输入-9999,则无叶子输出,sum=0o
2.【全国专升本统考题】写出求二叉树深度的算法,先定义二叉树的抽象数据类型。
(10分)
或【严题集6.44④】编写递归算法,求二叉树中以元素值为x的结点为根的子树的深度。
答;设计思路:
只查后继链表指针,若左或右孩子的左或右指针非空,则层次数加1;否则函数返回。
但注意,递归时应当从叶子开始向上计数,否则不易确定层数。
19
else{d=depth(root->lchild);
if(d>p)p=d;/*向上回朔时,要挑出左右
子树中的相对大的那个深度值*/
d=depth(root->rchild);
if(d>p)p=d;
}
p=p+1;
return(p);
}
法二:
intGet_Sub_Depth(BitreeT,intx)〃求二叉树中以值为x
的结点为根的子树深度
{
if(T->data==x)
{
printf("%d\n",Get_Depth(T));//找到了值为x的结
20
点,求其深度
exit1;
}
}
else
{
if(T->lchild)Get_Sub_Depth(T->lchild,x);if(T->rchild)Get_Sub_Depth(T->rchild,x);//在左右子树中继续寻找
}
}//Get_Sub_Depth
intGet_Depth(BitreeT)//求子树深度的递归算法
{
if(!
T)return0;
else
{
m=Get_Depth(T->lchild);
n=Get_Depth(T->rchild);return(m>n?
m:
n)+1;
}
}//Get_Depth
附:
上机调试过程
21
步骤1键盘输入序列12,8,17,11,16,2,13,9,
21,4,构成一棵二叉排序树。
层数应当为4
12
步骤2:
执行求深度的函数,并打印统计出来的深度值。
完整程序如下:
#includevstdio.h>
#includevstdlib・h>
typedefstructliuyu{intdata;structliuyu*lchild,*rchild;}test;
liuyu*root;
/*如何生成二叉排序
intsum=0;intm=sizeof(test);
voidinsert_data(intx)树?
参见教材P43C程序*/{liuyu*p,*q,*s;s=(test*)malloc(m);s->data=x;s->lchild=NULL;s->rchild=NULL;
22
if(!
root){root=s;return;}
p=root;
while(p)/*如何接入二叉排序树的适
当位置*/
{q=p;
if(p->data==x){printf("dataalreadyexist!
\n");return;}elseif(xdata)p=p->lchild;elsep=p->rchild;
}
if(xdata)q->lchild=s;
elseq->rchild=s;
}
intdepth(liuyu*root)/*统计层数*/
{intd,p;/*注意每一层的局部变量
d,p都是各自独立的*/
p=0;
if(root==NULL)return(p);/*找到叶子之后才开始
统计*/
else{
d=depth(root->lchild);
if(d>p)p=d;/*向上回朔时,要挑出左右
子树中的相对大的那个深度值*/
d=depth(root->rchild);
23
if(d>p)p=d;
}
p=p+1;
return(p);
}
voidmain()/*先生成二叉排序树,再调用
深度遍历递归函数进行统计并输出*/
{inti,x;
i=1;
root=NULL;/*千万别忘了赋初值给
root!
*/
do{printf("pleaseinputdata%d:
",i);
i++;
scanf("%d",&x);/*从键盘采集数据,以
-9999表示输入结束*/
if(x==-9999){
printf("\nNowoutputdepthvalue=%d\n",depth(root));return;}
elseinsert_data(x);}/*调用插入数据元
素的函数*/
while(x!
=-9999);
return;}
24
执行结果:
IB(Inactivex)
inputdatal:
12
4
pie曰专&inputdata£j
8
inputdata3:
17
inputdataQ:
11
inputdataS:
1G
pleaseinputdataG:
2
inputdata?
:
13
pleaseinputdata8:
9
inputdata3:
21
inputdatalO:
斗
inputdatal1:
-999S
Nououtputd^pthvaluo='ti
3.【严题集6.47④】编写按层次顺序(同一层自左至右)遍历二叉树的算法。
或:
按层次输出二叉树中所有结点;
解:
思路:
既然要求从上到下,从左到右,则利用队列
存放各子树结点的指针是个好办法。
这是一个循环算法,用while语句不断循环,直到队空之后自然退出该函数。
技巧之处:
当根结点入队后,会自然使得左、右孩子结点入队,而左孩子出队时又会立即使得它的左右孩子结点入队,……以此产生了按层次输出的效果。
假设max已知*/
/*置空队*/
level(liuyu*T)
/*liuyu*T,*p,*q[100];{intf,r;
f=0;r=0;r=(r+1)%max;
25
q[r]=T;/*根结点进队*/
while(f!
=r)/*队列不空*/
{仁(f+1%max);
p=q[f];/*出队*/
printf("%d",p->data);/*打印根结点*/
/*若
/*若
if(p->lchild){r=(r+1)%max;q[r]=p->lchild;}左子树不空,则左子树进队*/
if(p->rchild){r=(r+1)%max;q[r]=p->rchild;}右子树不空,则右子树进队*/
}
return(0);
}
法二:
voidLayerOrder(BitreeT)〃层序遍历二叉树
{
InitQueue(Q);//建立工作队列
EnQueue(Q,T);
while(!
QueueEmpty(Q))
{
DeQueue(Q,p);
visit(p);if(p->lchil