浙大数据结构03-树1 树的同构 (25 分)

本文探讨了如何通过C++实现判断两个给定的二叉树是否同构的问题,通过递归算法比较节点元素和子树结构。通过实例展示了如何使用`BuildTree`函数构建树结构,并利用`Isomorphic`函数进行同构检查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

 

 

输入样例1(对应图1):

8
A 1 2
B 3 4
C 5 -
D - -
E 6 -
G 7 -
F - -
H - -
8
G - 4
B 7 6
F - -
A 5 1
H - -
C 0 -
D - -
E 2 -

输出样例1:

Yes

输入样例2(对应图2):

8
B 5 7
F - -
A 0 3
C 6 -
H - -
D - -
G 4 -
E 1 -
8
D 6 -
B 5 -
E - -
H - -
C 0 2
G - 3
F - -
A 1 4

输出样例2:

No

#include<iostream>
#include<cstdlib>
#include<cstdio>

using namespace std;

#define Null -1
#define Tree int
#define MaxTree 10

struct TreeNode
{
	char Element;
	Tree Left;
	Tree Right;
}tree1[MaxTree], tree2[MaxTree];

Tree BuildTree(struct TreeNode T[])
{
	int n, i, root = Null;
	char left, right;
	cin >> n;
	if(n)
	{
		int check[MaxTree+1] = {0};
		for(i=0; i<n; i++){
			cin >> T[i].Element >> left >> right;
			//判断左节点
			if(left == '-')
				T[i].Left = Null;       //该节点的左节点为空
			else{
				T[i].Left = left - '0';
				check[T[i].Left] = 1;   //证明下标为T[i].Left的节点不是根节点
			}
			//判断右节点
			if(right == '-')
				T[i].Right = Null;
			else{
				T[i].Right = right - '0';
				check[T[i].Right] = 1;
			}
		}
		for(i=0; i<n; i++)
			if(!check[i])               //寻找根节点
				break;
		root = i;
	}
	return root;
}

int Isomorphic(Tree R1, Tree R2)
{
	//判断是否同构,结构是否相等(左右子树是否都可以遍历 + 元素相等)
	//1-3:递归结束的条件
	//1.两个树均为空,同构,返回1。
	if((R1==Null) && (R2==Null))
		return 1;
	//2.一棵树为空,另外一棵树不为空,不同构,返回0。
	if( ((R1==Null) && (R2!=Null)) || ((R1!=Null)&&(R2==Null)) )
		return 0;
	//3.两棵树的根节点不相等,不同构。
	if(tree1[R1].Element != tree2[R2].Element)
		return 0;
	//4.两棵树的左子树均为空,则判断右子树是否同构。
	if(tree1[R1].Left == Null && tree2[R2].Left == Null)
		return Isomorphic(tree1[R1].Right, tree2[R2].Right);
	//5.左子树都不空,且双方左子树树根的元素值相等,判断左左同构,右右同构
	if((tree1[R1].Left!=Null && tree2[R2].Left!=Null) && tree1[tree1[R1].Left].Element==tree2[tree2[R2].Left].Element)
		return (Isomorphic(tree1[R1].Left, tree2[R2].Left) && Isomorphic(tree1[R1].Right, tree2[R2].Right));
	//6.左子树都不空,且双方左子树树根的元素值不相等,判断左右同构,右左同构。
	else
		return (Isomorphic(tree1[R1].Left, tree2[R2].Right) && Isomorphic(tree1[R1].Right, tree2[R2].Left));
}
int main()
{
	Tree tree11, tree22;
	tree11 = BuildTree(tree1);
	tree22 = BuildTree(tree2);

	if(Isomorphic(tree11, tree22))
		cout << "Yes" << '\n' ;
	else
		cout << "No" << '\n' ;

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值