浙江大学-陈越-数据结构-03-树1 树的同构 可通过C语言代码

虽然写出来了,但是判断同构时那些情况还是不知道怎么考虑全。
另外需要注意的是scanf时加\n的情况,网上有很多资料,这里采取的做法是另一篇博客中看到的将\n加到前面的做法,非常巧妙,具体见代码内注释。

#include <stdio.h>

#pragma warning( disable : 4996 )

#define MAXSIZE 10
#define Null -1

struct Node
{
	char letter;
	int left;
	int right;
}Tree1Node[MAXSIZE], Tree2Node[MAXSIZE];

// 将树的节点存入结构数组中,返回根节点的下标
int BuildTree(struct Node T[]);
// 判断两个树是不是同构的
int Isisomorphism(int R1, int R2);

int main()
{
	int Root1 = BuildTree(Tree1Node);
	int Root2 = BuildTree(Tree2Node);

	if (Isisomorphism(Root1, Root2))
		printf("%s", "Yes");
	else
		printf("%s", "No");

	return 0;
}

int BuildTree(struct Node T[])
{
	int NodeNum;
	char cl, cr;
	int check[MAXSIZE] = {0};
	scanf("%d\n", &NodeNum);
	if (NodeNum == 0)
		return Null;
	for (int i = 0; i < NodeNum; i++)
	{
		scanf("\n%c %c %c", &T[i].letter, &cl, &cr);// 把换行符放在前面吃掉前面scanf后的回车,而最后一个scanf不能有回车,一举两得
		if (cl == '-')
			T[i].left = Null;
		else
		{
			T[i].left = cl - '0';
			check[T[i].left] = 1;
		}	
		if (cr == '-')
			T[i].right = Null;
		else
		{
			T[i].right = cr - '0';
			check[T[i].right] = 1;
		}
	}

	for (int i = 0; i < NodeNum; i++)
	{
		if (!check[i])// 若check数组里某一个数不是i,则其下标就是根
			return i;
	}
}

int Isisomorphism(int R1, int R2)
{
	if (R1 == Null && R2 == Null)// 两个树都空
		//printf("%s", "Yes");// 不能直接打印,因为要递归
		return 1;
	if ( (R1 == Null && R2 != Null) || (R1 != Null && R2 == Null) )// 一个空另一个不空
		return 0;
	if (Tree1Node[R1].letter != Tree2Node[R2].letter)// 两个树都不空则比较根的字母是否相同
		return 0;
	if (Tree1Node[R1].left == Null && Tree2Node[R2].left == Null)// 12都无左子树
		return Isisomorphism(Tree1Node[R1].right, Tree2Node[R2].right);
	//if (Tree1Node[R1].right == Null && Tree2Node[R2].right == Null)// 12都无右子树
	//	return Isisomorphism(Tree1Node[R1].left, Tree1Node[R2].left);
	if ( (Tree1Node[R1].left != Null && Tree2Node[R2].left != Null) &&\
		(Tree1Node[Tree1Node[R1].left].letter == Tree2Node[Tree2Node[R2].left].letter) )// 左边都 不空且元素相同
			return ((Isisomorphism(Tree1Node[R1].left, Tree2Node[R2].left)) && \
			(Isisomorphism(Tree1Node[R1].right, Tree2Node[R2].right)));
	else
		return ((Isisomorphism(Tree1Node[R1].left, Tree2Node[R2].right)) && \
		(Isisomorphism(Tree1Node[R1].right, Tree2Node[R2].left)));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值