7-3 树的同构

这道题的关键是要将所有可能的条件都列出来,还有就是先把根结点找出来。我们对于这道题还必须要用一个结构数组的形式来模拟二叉树

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";
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

B程洪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值