MOOC 树的同构

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

原题链接

思路

  1. 二叉树表示
    采用结构数组表示二叉树:静态链表
#define MaxTree 10		//结构数组的最大容量
#define ElemType char
#define Tree int
#define Null -1

//结构数组表示树,静态链表
struct TreeNode
{
	ElemType Element;	//节点的值,此处为字符型
	Tree Left;			//指向左子树的值
	Tree Right;			//指向右子树的值
}T1[MaxTree], T2[MaxTree];		//两个结构数组,分别存放相应的节点
  1. 建二叉树
    返回根节点的值
//建二叉树
Tree BuildTree(struct TreeNode T[])
{
	char cl, cr;	//左右字符
	int check[MaxTree];	//用于检测根节点
	int Root = -1;	//空树对应的是-1!!!!!!!!!!!
	int i = 0;
	int N;		//节点个数
	cin >> N;
	if(N)
	{
		for(i=0; i<N; i++)
		{
			check[i] = 0;
		}
		for(i=0; i<N; i++)
		{
			cin >> T[i].Element >> cl >> cr;
			if(cl != '-')		//该节点的左子树不为空
			{
				T[i].Left = cl - '0';	//将字符转化为数字
				check[T[i].Left] = 1;	//该节点所对应的值已经被指向了,不可能为根节点了
			}
			else
			{
				T[i].Left = Null;	//左子树为空对应的left为空值为-1
			}
			if(cr != '-')
			{
				T[i].Right = cr - '0';
				check[T[i].Right] = 1;
			}
			else
			{
				T[i].Right = Null;
			}
		}

		for(i=0; i<N; i++)	//寻找根节点
		{
			if(!check[i])
				break;
		}
		Root = i;	//T[i]中没有任何节点left(cl)和right(cr)指向它,此种节点只有一个
	}
	return Root;
}
  1. 同构判别
    多种情况,需要递归实现
int Isomorphic(Tree R1, Tree R2)
{
	//两棵树均为空
	if((R1==Null) && (R2==Null))
	{
		return 1;
	}

	//R1和R2中有一个为空
	if(((R1==Null)&&(R2!=Null)) || ((R1!=Null)&&(R2==Null)))
	{
		return 0;	//不同构
	}

	//R1和R2树的根节点的值都不相等
	if(T1[R1].Element != T2[R2].Element)
	{
		return 0;	//不同构
	}

	//R1和R2的左子树均为空,就只需比较其右子树是否同构
	if((T1[R1].Left==Null) && (T2[R2].Left==Null))
	{
		return Isomorphic(T1[R1].Right, T2[R2].Right);
	}

	//如果第一棵树和第二棵树的左子树不为空且值相等,故只需要比较右子树
	//如果第一棵树和第二棵树的左子树不为空且值不相等,则需要比较其左右子树交换后的结果
	if(((T1[R1].Left!=Null)&&(T2[R2].Left!=Null)) &&
		((T1[T1[R1].Left].Element==T2[T2[R2].Left].Element)))
	{
		return (Isomorphic(T1[R1].Left, T2[R2].Left) &&
				Isomorphic(T1[R1].Right, T2[R2].Right));
	}
	else
	{
		return(Isomorphic(T1[R1].Left, T2[R2].Right) &&
				Isomorphic(T1[R1].Right, T2[R2].Left));
	}
}

完整程序:

#include <iostream>
using namespace std;

#define MaxTree 10		//结构数组的最大容量
#define ElemType char
#define Tree int
#define Null -1

//结构数组表示树,静态链表
struct TreeNode
{
	ElemType Element;	//节点的值,此处为字符型
	Tree Left;			//指向左子树的值
	Tree Right;			//指向右子树的值
}T1[MaxTree], T2[MaxTree];		//两个结构数组,分别存放相应的节点


//建二叉树
Tree BuildTree(struct TreeNode T[])
{
	char cl, cr;	//左右字符
	int check[MaxTree];	//用于检测根节点
	int Root = -1;	//空树对应的是-1!!!!!!!!!!!
	int i = 0;
	int N;		//节点个数
	cin >> N;
	if(N)
	{
		for(i=0; i<N; i++)
		{
			check[i] = 0;
		}
		for(i=0; i<N; i++)
		{
			cin >> T[i].Element >> cl >> cr;
			if(cl != '-')		//该节点的左子树不为空
			{
				T[i].Left = cl - '0';	//将字符转化为数字
				check[T[i].Left] = 1;	//该节点所对应的值已经被指向了,不可能为根节点了
			}
			else
			{
				T[i].Left = Null;	//左子树为空对应的left为空值为-1
			}
			if(cr != '-')
			{
				T[i].Right = cr - '0';
				check[T[i].Right] = 1;
			}
			else
			{
				T[i].Right = Null;
			}
		}

		for(i=0; i<N; i++)	//寻找根节点
		{
			if(!check[i])
				break;
		}
		Root = i;	//T[i]中没有任何节点left(cl)和right(cr)指向它,此种节点只有一个
	}
	return Root;
}


int Isomorphic(Tree R1, Tree R2)
{
	//两棵树均为空
	if((R1==Null) && (R2==Null))
	{
		return 1;
	}

	//R1和R2中有一个为空
	if(((R1==Null)&&(R2!=Null)) || ((R1!=Null)&&(R2==Null)))
	{
		return 0;	//不同构
	}

	//R1和R2树的根节点的值都不相等
	if(T1[R1].Element != T2[R2].Element)
	{
		return 0;	//不同构
	}

	//R1和R2的左子树均为空,就只需比较其右子树是否同构
	if((T1[R1].Left==Null) && (T2[R2].Left==Null))
	{
		return Isomorphic(T1[R1].Right, T2[R2].Right);
	}

	//如果第一棵树和第二棵树的左子树不为空且值相等,故只需要比较右子树
	//如果第一棵树和第二棵树的左子树不为空且值不相等,则需要比较其左右子树交换后的结果
	if(((T1[R1].Left!=Null)&&(T2[R2].Left!=Null)) &&
		((T1[T1[R1].Left].Element==T2[T2[R2].Left].Element)))
	{
		return (Isomorphic(T1[R1].Left, T2[R2].Left) &&
				Isomorphic(T1[R1].Right, T2[R2].Right));
	}
	else
	{
		return(Isomorphic(T1[R1].Left, T2[R2].Right) &&
				Isomorphic(T1[R1].Right, T2[R2].Left));
	}
}

int main()
{
	Tree R1, R2;
	R1 = BuildTree(T1);	//建二叉树,返回根节点的值
	R2 = BuildTree(T2);

	if(Isomorphic(R1, R2))	//判断是否同构
	{
		cout << "Yes" << endl;
	}
	else
	{
		cout << "No" << endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/HdUIprince/article/details/83096603