收藏 分享(赏)

第6章习题答案.doc

上传人:yjrm16270 文档编号:5884888 上传时间:2019-03-20 格式:DOC 页数:11 大小:172.50KB
下载 相关 举报
第6章习题答案.doc_第1页
第1页 / 共11页
第6章习题答案.doc_第2页
第2页 / 共11页
第6章习题答案.doc_第3页
第3页 / 共11页
第6章习题答案.doc_第4页
第4页 / 共11页
第6章习题答案.doc_第5页
第5页 / 共11页
点击查看更多>>
资源描述

1、第 6 章 树与二叉树1习题 61.树与二叉树之间有什么区别与联系?解:树与二叉树逻辑上都是树形结构,区别有三点:(1)二叉树的度至多为 2,树无此限制。(2)二叉树有左右子树之分,树无此限制。(3)二叉树允许为空,树一般不允许为空。二叉树不是树的特例。2.高度为 的完全二叉树至少有多少个结点?至多有多少个结点?h解:至少有 个结点,至多有 个结点。 和结点数 之间的关系是 +1。1212hhnhn2log3.已知 A1n是一棵顺序存储的完全二叉树,如何求出 Ai和 Aj的最近的共同祖先?解:根据顺序存储的完全二叉树的性质,编号为 i 的结点的双亲的编号为i/2,故 Ai和 Aj的最近的共同祖

2、先可如下求出:while(i/2!j/2)if(ij)i=i/2;else j=j/2;退出 while 后,若 i/2=0,则最近共同祖先为根结点,否则共同祖先为 i/2。4.已知 A1n是一棵顺序存储的完全二叉树,求序号最小的叶子结点的下标。解:根据完全二叉树的性质,最后一个结点(编号为 n)的双亲结点的编号是n/2,这是最后一个分支结点,在它之后是第一个叶子结点,故序号最小的叶子结点的下标是n/2+1。5.一棵深度为 L 的满 k 叉树有以下性质:第 L 层上的结点都是叶子结点,其余各层上每个结点都有k 棵非空子树,如果按层次顺序从 1 开始对全部结点进行编号,求:(1)各层的结点数是多

3、少?(2)编号为 n 的结点的双亲结点(若存在)的编号是多少?(3)编号为 n 的结点的第 i 个孩子结点(若存在)的编号是多少?(4)编号为 n 的结点有左右兄弟结点的条件是什么?如果有,其右兄弟结点的编号是多少?解:(1)k h-1(h 为层数)。(2)因为该树上每层上均有 kh-1个结点,从根开始编号为 1,则结点 i 的从右向左数第 2 个孩子的结点编号为 ki。设 n 为结点 i 的子女,则关系式(i-1)*k+2 n i*k+1 成立,因 i 是整数,故结点 n 的双亲 i 的编号为n/k+1。(3)结点(n1)的前一结点编号为 n-1(其最右边子女编号是(n-1)*k+1),故结

4、点 n 的第 i 个孩子的编号是(n-1)*k+1+i。(4)根据以上分析,结点 n 有右兄弟的条件是,它不仅双亲的从右边的第一个子女,即(n-1)%k!=0,第 6 章 树与二叉树2其右兄弟编号是 n+1。6.试证明,在具有 n(n1)个结点的 m 叉树中,有 n(m-1)+1 个指针域是空的。解:具有 n 个结点的 m 叉树共用 n*m 个指针。除根结点外,其余 n-1 个结点均有指针所指,故空指针数为 n*m-(n-1)=n*(m-1)+1。7.试找出满足下列条件的二叉树:(1)先序序列与后序序列相同;(2)中序序列与后序序列相同;(3)先序序列与中序序列相同;(4)中序序列与层次遍历序

5、列相同。解:(1)若先序序列与后序序列相同,则或为空树,或为只有根结点的二叉树。(2)若中序序列与后序序列相同,则或为空树,或为任一结点至多只有左子树的二叉树。(3)若先序序列与中序序列相同,则或为空树,或为任一结点至多只有右子树的二叉树。(4)若中序序列与层次遍历序列相同,则或为空树,或为任一结点至多只有右子树的二叉树。8.设有一棵二叉树的层次遍历序列为 ABCDEFGHIJ,中序遍历序列为 DBGEHJACIF。请画出这棵二叉树。解:按层次遍历,第一个结点(树不空)为根,该结点在中序序列中把序列分成左右两部分左子树和右子树。若左子树不空,层次序列中第二个结点为左子树的根;若左子树为空,则层

6、次序列中第二个结点为右子树的根。对右子树分析类似。层次序列的特点是:从左到右每个结点或是当前情况下子树的根或是叶子。9.用一维数组存放一棵完全二叉树:ABCDEFGHIJKL。请写出后序遍历该二叉树的访问结点序列。解:HIDJKEBLFGCA。10.已知一棵二叉树的中序遍历序列为 DGBAECHIF,后序遍历序列为:GDBEIHFCA。(1)试画出该二叉树;(2)试画出该二叉树的中序线索树;(3)试画出该二叉树对应的森林。解:(1)ABC FGHIDE第 6 章 树与二叉树3(2)略(3)11.设有正文 AADBAACACCDACACAAD,字符集为 A、B、C、D,设计一套二进制编码,使得上

7、述正文的编码最短。解:字符 A、B、C、D 出现的次数为 9、1、5、3。其哈夫曼编码如下:A:1,B:000,C:01,D:001。其哈夫曼树为:12.假设一个仅包含二元运算符的算术表达式以链表形式存储在二叉树 T 中,写出计算该算术表达式值的算法。解:typedef struct NodeElemType data;float val;char optr;/只取+、-、*、/struct Node *lchild,*rchildABD EFHIG CABD E FHIGC1 359000111第 6 章 树与二叉树4BiNode,*BiTree;float PostEval(BiTree

8、t)/以后序遍历算法求以二叉树表示的算术表达式的值float lv,rv;if(t!=NULL)lv=PostEval(t-lchild);/rv=PostEval(t-rchild);/switch(t-optr)case +: value=lv+rv;break;case -:value=lv-rv;break;case *:value=lv*rv;break;case /:value=lv/rv;break;return value;13.假设二叉链表为二叉树的存储结构,编写判断给定的二叉树是否相似的算法。所谓二叉树 t1 和t2 相似指的是:t1 和 t2 都是空树;或者 t1 和 t

9、2 的根结点是相似的,以及 t1 的左子树和 t2 的左子树是相似的且 t1 的右子树和 t2 的右子树是相似的。解:int Like(BiTree t1, BiTree t2)int like1,like2;if(t1=NULLelse if(t1=NULL|t2=NULL)return 0;elselike1=Like(t1-lchild,t2-lchild);like2=Like(t1-rchild,t2-rchild);return (like1 14.假设二叉链表为二叉树的存储结构,编写递归算法,将二叉树中所有结点的左、右子树相互交换。解:void Exchange(BiTree s

10、=t-lchild;t-lchild=t-rchild;t-rchild=s;Exchange(t-lchild);Exchange(t-rchild);15.编写求双亲表示法表示的树的深度的算法。解:int Depth(PTree t)int maxdepth=0,i,temp,f;for(i=0;i-1)temp+;f=t.nodesf.parent;if(tempmaxdepth)maxdepth=temp;return maxdepth;16.假设二叉链表为二叉树的存储结构,编写按层次遍历方式计算二叉树结点个数的算法。解:int Level(BiTree t)int num=0;Lin

11、kQueue Q;BiTree p;if(t)InitQueue(Q);EnQueue(Q,t);while(!QueueEmpty(Q)DeQueue(Q,p);num+;if(p-lchild)EnQueue(Q,p-lchild);if(p-rchild)EnQueue(Q,p-rchild);/while/ifreturn num;17.编写算法,利用叶子结点中的空指针域将所有叶子结点链接为一个带有头结点的双向链表,算法第 6 章 树与二叉树6返回头结点的指针。解:BiTree head,pre;/全局变量链表头指针 head,prevoid CreateLeafList(BiTree

12、 t)if(t)CreateLeafList(t-lchild);/中序遍历左子树if(t-lchild=NULL /生成头结点head-lchild=NULL; head-rchild=t;/头结点的左链为空,右链指向第一个叶子结点t-lchild=head;pre=t;/第一个叶子结点左链指向头结点,pre 指向当前叶子结点elsepre-rchild=t;t-lchild=pre;pre=t;CreateLeafList(t-rchild);pre-rchild=NULL; 18.假设二叉链表为二叉树的存储结构,编写算法,按照括号表示法输出二叉树的所有结点。解:其过程是:对于非空二叉树

13、t,先输出其元素值,当存在左孩子结点或右孩子结点时,输出一个“(”符号,然后递归处理左子树,输出一个“,”符号,递归处理右子树,最后输出一个“)”符号。void DispBiTree(BiTree t)if(t)printf(“%c“,t-data);if(t-lchild!=NULL|t-rchild!=NULL)printf(“(“);DispBiTree(t-lchild);if(t-rchild!=NULL) printf(“,“);DispBiTree(t-rchild);printf(“)“);19.假设二叉链表为二叉树的存储结构,编写算法,输出二叉树的所有叶子结点。第 6 章 树

14、与二叉树7解:void DispLeaf(BiTree t)if(t)if(t-lchild=NULLDispLeaf(t-lchild);DispLeaf(t-rchild);20.假设二叉链表为二叉树的存储结构,编写算法,输出值为 x 的结点的所有祖先。解:int Ancestor(BiTree t,ElemType x)if(t=NULL)return 0;if(t-data=x)return 1;if(Ancestor(t-lchild,x)|Ancestor(t-rchild,x)printf(“%c “,t-data);return 1;21.假设二叉链表为二叉树的存储结构,编写算

15、法,输出所有叶子结点到根结点的路径。解:利用后序非递归遍历的特点,将其中访问结点改为判断结点是否为叶子结点,若是,输出栈中所有结点值void AllPathAncestor(BiTree t)BiTNode *St100;BiTNode *p;int flag,i,top=-1;/栈指针初始化if(t)dowhile(t) /t 的所有左结点进栈top+;Sttop=t;t=t-lchild;p=NULL; /p 指向栈顶结点的前一个已访问的结点flag=1; /设置 t 的访问标记为已访问过第 6 章 树与二叉树8while(top!=-1 /出栈if(t-rchild=p)if(t-lch

16、ild=NULLi0;i-) printf(“%c-“,Sti-data); /输出栈中所有结点printf(“%cn“,St0-data);top-;p=t;/p 指向刚访问过的结点elset=t-rchild; /t 指向右孩子结点flag=0; /设置未访问标记while(top!=-1);printf(“n“);22.编写算法,将二叉树的顺序存储结构转化为二叉链表存储结构。解:typedef char ElemType;typedef struct /结点结构ElemType *data;/数据元素int n;/左右孩子指针SqBTree;BiTree Trans(SqBTree a,

17、int i)/数据元素放在数组 a 的从下标为 1 开始的单元中BiTree t;if(ia.n)return NULL;/当 i 大于 a 的结点个数if(a.datai=#)return NULL;/当 i 对于的结点为空t=new BiTNode;t-data=a.datai;t-lchild=Trans(a,2*i);t-rchild=Trans(a,2*i+1);return t;第 6 章 树与二叉树923.写出在中序线索二叉树中找指定结点在后序下的前驱结点的算法。解:在后序序列中,若结点 p 有右子女,则右子女是其前驱,若无右子女而有左子女,则左子女是其前驱。若 p 左右子女均无

18、,设其中序左线索指向其祖先结点 f(p 是 f 右子树中按中序遍历的第一个结点),若 f 有左子女,则其右子女是 p 在后序下的前驱,若 f 无左子女,则顺其前驱找双亲的双亲,一直继续到双亲有左子女(这时左子女是 p 的前驱)。还有一种情况,若 p 是中序遍历的第一个结点,p 在中序和后序下均无前驱。BiThrTree InPostPre(BiThrTree t,BiThrTree p)BiThrNode *q;if(p-RTag=0)q=p-rchild;/若 p 有右子女,则右子女是其后序前驱else if(p-LTag=0)q=p-lchild; /若 p 无右子女而有左子女,则左子女是

19、其后序前驱else if(p-lchild=NULL)q=NULL;/p 是中序序列第一个结点,无后序前驱else /顺左线索向上找 p 的祖先,若存在,再找祖先的左子女while(p-LTag=1if(p-LTag=0)q=p-lchild; /p 结点的祖先的左子女是其后序前驱else q=NULL; /仅右单支树(p 是叶子),已上到根结点,p 结点无后序前驱return q;24.写出按后序序列遍历中序线索二叉树的算法。解:BiThrTree LeftMost(BiThrTree t)/求结点 t 的最左子孙的左线索BiThrTree p=t;while(p-LTag=0)p=p-lc

20、hild;if(p-lchild!=NULLelse return NULL;BiThrTree RightMost(BiThrTree t)/求结点 t 的最右子孙的右线索BiThrTree p=t;while(p-RTag=0)p=p-rchild;if(p-rchild!=NULLelse return NULL;int ISRightChild(BiThrTree t,BiThrTree if(fatherelse return 0;void PostOrderInThr(BiThrTree t)/后序遍历中序线索二叉树 tBiThrTree father,p=t-lchild;int

21、 flag;while(p!=t)while(p-LTag=0)p=p-lchild;/沿左分子向下if(p-RTag=0)flag=0;/左孩子为线索,右孩子为链,相当从左返回,p 为叶子,相当从右返回else flag=1;while(flag=1)printf(“%c“,p-data); /访问结点if(ISRightChild(p,father)p=father;flag=1; /修改 p 指向双亲else/p 是左孩子,用最右子孙的右线索找双亲p=RightMost(p);if(pelse flag=0;/while(flag=1)if(flag=0/转向当前结点的右分支25.已知中

22、序线索二叉树 T 的右子树不空。设计算法,将 s 所指结点作为 T 的右子树的一个叶子结点插入进去,并使之成为 T 的右子树的(中序序列)第一个结点。解:若使新插入的结点 S 成 T 右子树中序序列的第一个结点,则应在 T 的右子树中最左边的结点(设为 p)处插入,使 S 成为结点 p 的左孩子。则 S 的前驱是 T,后继是 p。void ThrTreeInsert(BiThrTree T, BiThrTree S)BiThrTree p=T-rchild;/用 p 指向 T 的右子树中最左边的结点while(p-LTag=0)p=p-lchild;S-LTag=1;S-RTag=1;/S 是

23、叶子结点,其左右标记均为 1S-lchild=p-lchild; S-rchild=p;/S 的前驱是根结点 T,后继是结点 pp-lchild=S; p-LTag=0;/将 p 的左指针指向 S,并修改左标记为 0第 6 章 树与二叉树1126.写出在中序线索二叉树中找指定结点在中序下的前驱结点的算法。解:BiThrTree InorderPre(BiThrTree p)BiThrTree q;if(p-LTag=1)/结点的左子树为空,结点左指针域为左线索,指向其前驱return(p-lchild);elseq=p-lchild;/p 结点左子树最右边结点时 p 结点的中序前驱while(q-RTag)q=q-rchild;return q;/if

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 中等教育 > 试题课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报