这道题的关键是要将所有可能的条件都列出来,还有就是先把根结点找出来。我们对于这道题还必须要用一个结构数组的形式来模拟二叉树
struct treenode
{
char ment;存成员
int left,right;存右,左孩子结点下标
}tree1[20],tree2[20];
因为这道题的输入顺序就是该结点的下标所以我们可以采用这种方法。找根结点的方法其实也简单,就是如果该结点有父亲结点,就将该节点对应地址的一个数组元素变为它父亲的下标,这个设初值为-1.之后再遍历一遍,如果某个结点还是保持初值-1,它就是根结点。最后返回根结点的下标。具体操作方法如下。
int creat(treenode tree[])
{
int num;cin>>num;
if(num==0)return -1;
int flag[num];
for(int i=0;i<num;i++)flag[i]=0;
for(int i=0;i<num;i++)
{
char name,le,ri;cin>>name>>le>>ri;//这里我们用读字符的方式方便一点
tree[i].ment=name;
if(le!='-')
{
tree[i].left=le-'0';
flag[tree[i].left]=1;
}
else tree[i].left=-1;
if(ri!='-')
{
tree[i].right=ri-'0';
flag[tree[i].right]=1;
}
else tree[i].right=-1;
}
for(int i=0;i<num;i++)
{
if(flag[i]==0)return i;
}
}
接下来就是本题的判断核心了
具体代码中见
int find(int root1, int root2)
{
if (root1 == -1 && root2 == -1)这个是两个结点都到头了或者是两个结点原来都是空的,属于同构情况
return 1;
if (root1 == -1 && root2 != -1 || root1 != -1 && root2 == -1)
return 0;这个就是当两个结点一个为空一个不为空,这个时候肯定不为同构情况
if (tree1[root1].ment != tree2[root2].ment)
return 0;当前元素不同,必然不同构
if (tree1[root1].left == -1 && tree2[root2].left == -1)这个是当左子树同为空,走右子树
{
return find(tree1[root1].right, tree2[root2].right);
}
if (tree1[root1].right == -1 && tree2[root2].right == -1)与上一个一样
{
return find(tree1[root1].left, tree2[root2].left);
}
if (((tree1[root1].left != -1) && (tree2[root2].left != -1)) &&((tree1[tree1[root1].left].ment) == (tree2[tree2[root2].left].ment)))这个是如果两个左子树都不为空且左子树下一层的元素都一样,看看左子树的元素,和右子树的元素是否可以同时同构。
{
return (find(tree1[root1].left, tree2[root2].left) && find(tree1[root1].right, tree2[root2].right));
}
else
return (find(tree1[root1].left, tree2[root2].right) && find(tree1[root1].right, tree2[root2].left));最后就是左右子树的元素都同构,成立。
}
之后附上本题的具体代码
#include<bits/stdc++.h>
using namespace std;
struct treenode
{
char ment;
int left,right;
}tree1[20],tree2[20];
int creat(treenode tree[])
{
int num;cin>>num;
if(num==0)return -1;
int flag[num];
for(int i=0;i<num;i++)flag[i]=0;
for(int i=0;i<num;i++)
{
char name,le,ri;cin>>name>>le>>ri;
tree[i].ment=name;
if(le!='-')
{
tree[i].left=le-'0';
flag[tree[i].left]=1;
}
else tree[i].left=-1;
if(ri!='-')
{
tree[i].right=ri-'0';
flag[tree[i].right]=1;
}
else tree[i].right=-1;
}
for(int i=0;i<num;i++)
{
if(flag[i]==0)return i;
}
}
int find(int root1,int root2)
{
if(root1==-1&&root2==-1)return 1;
if(root1==-1&&root2!=-1||root1!=-1&&root2==-1)return 0;
if(tree1[root1].ment!=tree2[root2].ment)return 0;
if(tree1[root1].left==-1&&tree2[root2].left==-1)
{
return find(tree1[root1].right,tree2[root2].right);
}
if(tree1[root1].right==-1&&tree2[root2].right==-1)
{
return find(tree1[root1].left,tree2[root2].left);
}
if(((tree1[root1].left!=-1)&&(tree2[root2].left!=-1))
&&((tree1[tree1[root1].left].ment)==(tree2[tree2[root2].left].ment)))
{
return (find(tree1[root1].left,tree2[root2].left)&&find(tree1[root1].right,tree2[root2].right));
}
else return (find(tree1[root1].left,tree2[root2].right)&&find(tree1[root1].right,tree2[root2].left));
}
int main()
{
int root1=creat(tree1);
int root2=creat(tree2);
if(find(root1,root2))cout<<"Yes";
else cout<<"No";
}