数据结构各章习题及答案!! 下载本文

后继线索的指针。19. 1,RChild

20. 本节中我们学习的树的存储结构有_____________、___________和___________。20. 孩子表示法,双亲表示法,长子兄弟表示法

四、应用题

1. 已知一棵树边的集合为{},请画出这棵树,并回答下列问题:

(1)哪个是根结点? (2)哪些是叶子结点? (3)哪个是结点g的双亲? (4)哪些是结点g的祖先? (5)哪些是结点g的孩子? (6)哪些是结点e的孩子?

(7)哪些是结点e的兄弟?哪些是结点f的兄弟? (8)结点b和n的层次号分别是什么? (9)树的深度是多少?

(10)以结点c为根的子树深度是多少? 1. 解答: 根据给定的边确定的树如图5-15所示。 a 其中根结点为a; c b 叶子结点有:d、m、n、j、k、f、l;

c是结点g的双亲;

g f h d e

a、c是结点g的祖先;

j、k是结点g的孩子; i i k j m、n是结点e的子孙;

m n e是结点d的兄弟;

g、h是结点f的兄弟;

图5-15

结点b和n的层次号分别是2和5; 树的深度为5。

2. 一棵度为2的树与一棵二叉树有何区别。 2. 解答: 度为2的树有两个分支,但分支没有左右之分;一棵二叉树也有两个分支,但有左右之分,左右子树不能交换。

3. 试分别画出具有3个结点的树和二叉树的所有不同形态? 3. 解答: 略

4. 已知用一维数组存放的一棵完全二叉树:ABCDEFGHIJKL,写出该二叉树的先序、中序和后序遍历序列。 4. 解答:

先序序列:ABDHIEJKCFLG 中序序列:HDIBJEKALFCG

后序序列:HIDJKEBLFGCA

5. 一棵深度为H的满k叉树有如下性质:第H层上的结点都是叶子结点,其余各层上每个结点都有k棵非空子树,如果按层次自上至下,从左到右顺序从1开始对全部结点编号,回答下列问题:

(1)各层的结点数目是多少?

(2)编号为n的结点的父结点如果存在,编号是多少?

(3)编号为n的结点的第i个孩子结点如果存在,编号是多少?

(4)编号为n的结点有右兄弟的条件是什么?其右兄弟的编号是多少? 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)它们在先序遍历和后序遍历时,得到的遍历序列相同; 6. 解答: (1)先序序列和中序序列相同的二叉树为:空树或者任一结点均无左孩子的非空二叉树; (2)中序序列和后序序列相同的二叉树为:空树或者任一结点均无右孩子的非空二叉树; (3)先序序列和后序序列相同的二叉树为:空树或仅有一个结点的二叉树。

7. 假设一棵二叉树的先序序列为EBADCFHGIKJ,中序序列为ABCDEFGHIJK,请写出该二叉树的后序遍历序列。

7. 解答:后序序列:ACDBGJKIHFE

8. 假设一棵二叉树的后序序列为DCEGBFHKJIA,中序序列为DCBGEAHFIJK,请写出该二叉树的后序遍历序列。

8. 解答:先序序列:ABCDGEIHFJK

9. 给出如图5-14所示的森林的先根、后根遍历结点序列,然后画出该森林对应的二叉树。

9. 解答: 先根遍历:ABCDEFGHIJKLMNO 后根遍历:BDEFCAHJIGKNOML 森林转换成二叉树如图5-16所示。

10.给定一组权值(5,9,11,2,7,16),试设计相应的哈夫曼树。 10. 解答:构造而成的哈夫曼树如图5-17所示。

A

G

C

K I

L

B

H

M D

E

F

J

N

O

五、算法设计题

1. 一棵具有n个结点的完全二叉树以一维数组作为存储结构,试设计一个对该完全二叉树进行先序遍历的算法。

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. 给定一棵用二叉链表表示的二叉树,其中的指针t指向根结点,试写出从根开始,按层次遍历二叉树的算法,同层的结点按从左至右的次序访问。

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

{ 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. 写出在中序线索二叉树中结点P的右子树中插入一个结点s的算法。

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. 给定一棵二叉树,用二叉链表表示,其根指针为t,试写出求该二叉树中结点n的双亲结点的算法。若没有结点n或者该结点没有双亲结点,分别输出相应的信息;若结点n有双亲,输出其双亲的值。

4. 解答:利用一个队列来完成,设该队列类型为指针类型,最大容量为maxnum。算法中的front为队头指针,rear为队尾指针,若当前队头结点的左、右子树的根结点不是所求结点,