习题5参考答案
一、单项选择题
1. C 2. B 3. C 4. D 5. B 6. D 7. C 8. B 9. B 10. B 11. A 12. D 13. A 14. B 15. A 二、判断题
1.× 2.√ 3.× 4.√ 5.× 6.√ 7.√ 8.√ 9.× 10.× 三、填空题
1. 3,4,6,1,1,2,A,F,G 2. n+1
3. 完全,??log2(n?1)??,最大,n
4. 55 5. 中序
6. 2n,n-1,n+1 7. n2+1
8. 2k-1,2k-1,2k-1 9. 5 10. 2h-1
11. 单支树,完全二叉树
12. 2i,2i+1,i/2(或?i/2?) 13. 2n,n-1,n+1
14. 带权路径长度最小
15. 结点数为0,只有一个根结点的树 16. 二叉链表,三叉链表 17. 双亲结点
18. 指向结点前驱和后继信息的指针 19. 1,RChild
20. 孩子表示法,双亲表示法,长子兄弟表示法 四、应用题
1. 解答: 根据给定的边确定的树如图5-15所示。 a 其中根结点为a;
叶子结点有:d、m、n、j、k、f、l; b c c是结点g的双亲;
d
e g f h i j
k i
m n 图5-15
-26-
a、c是结点g的祖先; j、k是结点g的孩子; m、n是结点e的子孙; e是结点d的兄弟; g、h是结点f的兄弟;
结点b和n的层次号分别是2和5; 树的深度为5。 2. 解答: 度为2的树有两个分支,但分支没有左右之分;一棵二叉树也有两个分支,但有左右之分,左右子树不能交换。 3. 解答: 略 4. 解答:
先序序列:ABDHIEJKCFLG 中序序列:HDIBJEKALFCG 后序序列:HIDJKEBLFGCA 5. 解答: (1)第i层上的结点数目是mi-1。
(2)编号为n的结点的父结点如果存在,编号是((n-2)/m)+1。
(3)编号为n的结点的第i个孩子结点如果存在,编号是(n-1)*m+i+1。
(4)编号为n的结点有右兄弟的条件是(n-1)%m≠0。其右兄弟的编号是n+1。 6. 解答: (1)先序序列和中序序列相同的二叉树为:空树或者任一结点均无左孩子的非空二叉树; (2)中序序列和后序序列相同的二叉树为:空树或者任一结点均无右孩子的非空二叉树; (3)先序序列和后序序列相同的二叉树为:空树或仅有一个结点的二叉树。 7. 解答:后序序列:ACDBGJKIHFE 8. 解答:先序序列:ABCDGEIHFJK 9. 解答: 先根遍历:ABCDEFGHIJKLMNO 后根遍历:BDEFCAHJIGKNOML 森林转换成二叉树如图5-16所示。
10. 解答:构造而成的哈夫曼树如图5-17所示。
A
50 B G
30 20 C H K
D E F J I M N O 图5-16
L 9 11 14 7 7 2 图5-17
16 5 -27-
五、算法设计题
1. 解答:这个问题可以用递归算法,也可用非递归算法,下面给出的为非递归算法。假设该完全二叉树的结点以层次为序,按照从上到下,同层从左到右顺序编号,存放在一个一维数组R[1..n]中,且用一个有足够大容量为maxlen的顺序栈作辅助存储,算法描述如下:
preorder (R) //先序遍历二叉树R int R[n]; { int root;
SqStack *s; //s为一个指针栈,类型为seqstack,其中包含top域和数组data s->top= -1; //s栈置空 root=1;
while ((root<=n) && (s->top>-1)) { while (root<=n) { printf(R[root]); } }
s->top++; }
if (s->top>-1) //栈非空访问,遍历右子树 { root=s->data[s->top]*2+1; s->top--; }
s->data[s->top]=root; root=2*root;
2. 解答:考虑用一个顺序队que来保存遍历过程中的各个结点,由于二叉树以二叉链表存储,所以可设que为一个指向数据类型为bitree的指针数组,最大容量为maxnum,下标从1开始,同层结点从左到右存放。算法中的front为队头指针,rear为队尾指针。
levelorder (BiTree *t) //按层次遍历二叉树t { BiTree *que[maxnum]; int rear,front; if (t!=NULL)
{ front=0; //置空队列 rear=1; que[1]=t; do
-28-
{ front=front%maxsize+1; //出队 t=que[front]; printf(t->data);
if (t->lchild!=NULL) //左子树的根结点入队 { rear=rear%maxsize+1;
que[rear]=t->lchild; }
if (t->rchild!=NULL) //右子树的根结点入队 { rear=rear%maxsize+1; que[rear]=t->rchild;
}
}while (rear= =front); //队列为空时结束 }
}
3. 解答:设该线索二叉树类型为bithptr,包含5个域:lchild,ltag,data,rchild,rtag。
insert(p, s) //将s结点作为p的右子树插入 BiThrNode *p,*s; { BiThrNode *q;
if (p->rtag= =1) //无右子树,则有右线索 { s->rchild=p->rchild; s->rtag=1; p->rchild=s; p->rtag=0; } else
{ q=p->rchild;
while(q->ltag= =0) //查找p所指结点中序后继,即为其右子树中最左下的结点
q=q->lchild; q->lchild=p->rchild; s->rtag=0; p->rchild=s; }
s->lchild=p; //将s结点的左线索指向p结点 s->ltag=1; }
4. 解答:利用一个队列来完成,设该队列类型为指针类型,最大容量为maxnum。算法中的front为队头指针,rear为队尾指针,若当前队头结点的左、右子树的根结点不是所求结点,则将两子树的根结点入队,否则,队头指针所指结点即为结点的双亲。
-29-
parentjudge(t,n) BiTree *t; int n;
{ BiTree *que[maxnum]; int front,rear; BiTree *parent; parent=NULL; if (t)
if (t->data= =n)
printf(“no parent!”); //n是根结点,无双亲 else
{ front=0; //初始化队列 rear=1;
que[1]=t; //根结点进队 do
{ front=front%maxsize+1; t=que[front];
if((t->lchild->data= =n)|| (t->rchild->data= =n)) //结点n有双亲 { parent=t; front=rear;
printf(“parent”,t->data); } else
{ if (t->lchild!=NULL) //左子树的根结点入队 { rear=rear%maxsize+1; que[rear]=t->lchild;
}
if (t->rchild!=NULL) //右子树的根结点入队 { rear=rear%maxsize+1;
que[rear]=t->rchild; }
}
}while(rear= =front); //队空时结束 if (parent = =NULL) printf(“结点不存在”);
} }
-30-
百度搜索“70edu”或“70教育网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,70教育网,提供经典综合文库数据结构习题及参考答案(6)在线全文阅读。
相关推荐: