第五章学习小结
Posted dengyanlin321
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第五章学习小结相关的知识,希望对你有一定的参考价值。
本章学习心得:
本章我们学习了树与二叉树,里面涉及到的新概念,新知识很多,所以我对它们并不是特别熟悉,有时老师上课提到一些基本术语,我会突然想不起来它的定义,需要翻书看一下才知道。然后就是学到树的很多操作都是建立在对树的遍历上。所以我会多看几遍书,牢记基本术语。
做拼题a的时候发现很多概念感觉老师课上没有讲,比如说什么最小堆,二叉搜索树之类的,然后做选择判断题就做的比较吃力,因为要花时间去搜索相关定义和理解转换它们。做完选,择填空题发现自己的前中后序不是很熟练,特别是在做最后一道选择题时花了很长时间去研究这道题,后来翻看网上的做题思路,才有了想法并知道如何去做类似的题目了。但是选择第8题我看了答案,也不知道如何得出来的。
因为想讲两道题,所以我想讲的第一道题深入虎穴,就大概讲一下我觉得老师讲的解题方法中我第一次知道可以这样做的部分。
深入虎穴:
typedef struct{ int doors;//门的数量 int *p;//指向后面的门的编号序列 }node;
里面用指针根据门的数量分配空间并指向其后跟着的门的方法让我觉得非常新颖
for(i=1;i<=n;i++)//读入n扇门的信息 { cin>>a[i].doors; if(a[i].doors!=0) { a[i].p=new int[a[i].doors];//为a【i】.p申请空间 for(j=1;j<=a[i].doors;++j) { cin>>a[i].p[j-1]; vi[a[i].p[j-1]] =true; } }
这样做真的节省了很多空间。
树的同构:
其实我一开始以为这道题是建立在对树的遍历的基础上的,后来发现自己有点固定思维了,其实根本都用不到遍历。
我其实不是很会这道题,因为我参考了网上的解题思路,用了递归结构,但其实我有些地方并不是很理解。
int isomorphism(node a[],node b[],int x, int y) { if((x==-1)&&(y==-1))//如果是空树,则同构 return 1; if(((x==-1)&&(y!=-1))||((x!=-1)&&(y==-1))) return 0;//如果 一个为空另一个不为空则不是同构的 if(a[x].name!=b[y].name) return 0;//如果数据不同则不是同构的 if((a[x].lch==-1)&&(b[y].lch==-1)) return isomorphism( a, b, a[x].rch, b[y].rch);//如果左儿子为空,则判断右儿子是否同构 要看以上三个方面(1)右儿子是否都为空(2)是否一个有右儿子一个没有(3)右儿子数据是否相同 if(((a[x].lch!=-1)&&(b[y].lch!=-1))&&(a[a[x].lch].name==b[b[y].lch].name)) return (isomorphism( a,b,a[x].lch,b[y].lch)&&isomorphism( a,b,a[x].rch,b[y].rch));// 如果两棵树左儿子都不为空,而且数据相同,则对两棵树的左儿子进行递归 else return (isomorphism( a,b,a[x].lch,b[y].rch)&&isomorphism( a,b,a[x].rch,b[y].lch));//如果两棵树左儿子一个为空一个不为空,或者都为空,那么判断第一棵树左(右)儿子是否和第二棵树右(左)儿子 同构 }
我就不是很明白第二个if那里,我觉得第一棵树的左儿子(右儿子)为空,第二棵树的右儿子(左儿子)不为空,并不是不同构呀,可以第一棵树的左儿子为空,右儿子等于第二棵树的左儿子,第二棵树的右儿子为空,这样不也符合if里的条件吗?那就是同构的呀,为什么要返回0呢?
完整代码如下:
#include <iostream> using namespace std; typedef struct { char name; int lch; int rch; }node;//树的结点类型定义 int buildtree(node a[]); int isomorphism(node a[],node b[],int x, int y); int main() { node a[10],b[10];//定义两棵结点小于等于10的树 int x,y; x=buildtree(a); y=buildtree(b);// 构建两棵树,并传回两棵树的根节点 if(isomorphism(a,b,x,y))//树同构输出yes,否输出no { cout<<"Yes"; } else cout<<"No"; return 0; } int buildtree(node a[]) { char check[10]={false};//用来排查根节点 int N; cin>>N; if(N==0) return -1; for(int i=0;i<N;++i)//输入并保存树 { char x,y; cin>>a[i].name>>x>>y; if(x!=‘-‘) { a[i].lch=x-‘0‘; check[a[i].lch]=true; } else a[i].lch=-1; if(y!=‘-‘) { a[i].rch=y-‘0‘; check[a[i].rch]=true; } else a[i].rch=-1; } for(int i=0;i<N;++i) {//返回根节点 if(!check[i]) return i; } } int isomorphism(node a[],node b[],int x, int y) { if((x==-1)&&(y==-1))//如果是空树,则同构 return 1; if(((x==-1)&&(y!=-1))||((x!=-1)&&(y==-1))) return 0;//如果 一个为空另一个不为空则不是同构的 if(a[x].name!=b[y].name) return 0;//如果数据不同则不是同构的 if((a[x].lch==-1)&&(b[y].lch==-1)) return isomorphism( a, b, a[x].rch, b[y].rch);//如果左儿子为空,则判断右儿子是否同构 要看以上三个方面(1)右儿子是否都为空(2)是否一个有右儿子一个没有(3)右儿子数据是否相同 if(((a[x].lch!=-1)&&(b[y].lch!=-1))&&(a[a[x].lch].name==b[b[y].lch].name)) return (isomorphism( a,b,a[x].lch,b[y].lch)&&isomorphism( a,b,a[x].rch,b[y].rch));// 如果两棵树左儿子都不为空,而且数据相同,则对两棵树的左儿子进行递归 else return (isomorphism( a,b,a[x].lch,b[y].rch)&&isomorphism( a,b,a[x].rch,b[y].lch));//如果两棵树左儿子一个为空一个不为空,或者都为空,那么判断第一棵树左(右)儿子是否和第二棵树右(左)儿子 同构 }
以上是关于第五章学习小结的主要内容,如果未能解决你的问题,请参考以下文章