Isomorphism of trees

Written by Robert_Wang in Southwest University of Science And Technology.

7-3 Isomorphism of Trees (25 points)

Given two trees T1 and T2. Two trees are said to be "isomorphic" if T1 can be transformed into T2 by exchanging left and right children several times. For example, the two trees shown in Figure 1 are isomorphic, because we exchange the left and right children of nodes A, B, and G in one of the trees to get another tree. Figure 2 is not isomorphic.


figure 1


figure 2

Now given two trees, please judge whether they are isomorphic.

Input format:

The input gives the information of 2 binary tree trees. For each tree, first give a non-negative integer in one lineN (1 0 ), that is, the number of nodes in the tree (at this time, it is assumed that the nodes are from 0 toN 1 number); thenLine N , the firstLine i corresponds to the numberedi nodes, give an English capital letter stored in the node, the number of its left child node, and the number of its right child node. If the child node is empty, "-" is given in the corresponding position. The data given is separated by a space. Note: The title guarantees that the letters stored in each node are different.

Output format:

If the two trees are isomorphic, output "Yes", otherwise output "No".

Input example 1 (corresponding to Figure 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 -

Sample output 1:

Yes

Input example 2 (corresponding to Figure 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

Sample output 2:

No

Steps: Build a tree -> find the root node -> judge

1. Here a structure array is used to store the tree,

struct node
{
char data;
int lchild;
int rchild;

} Tree1 [MAX], Tree2 [MAX];

如果用链式的储存方式来储存,比较麻烦,所以改用int型的。注意建立的时候根节点要赋值为NULL,因为树根不存在的时候

,此树就不存在!!!

2找根节点

其实在建立树的时候用一个数组将每个出现的节点标记就可以了,检查一遍哪一个节点为出现过,即为根节点。

3.判断

这里需要逻辑清晰一点,传入放入参数是两个根节点 ra, rb,有一下几个判断条件

(1)ra , rb 都为空, 此步骤判断为真

(2)ra, rb 一个空,一个不空,此步骤判断为假。

(3)ra, rb的值不相等,此步骤判断为假

(4)ra->lchild与rb->lchild都为空,此时还要递归判断右子树

(4)ra->lchild与rb->lchild都不为空,ra->lchild的值与rb->lchild的值相等,此时还要递归判断右子树和左子树,否则交换左右再判断

#include<iostream>
#include<vector>
#include<algorithm>
#include<string.h>
#include<string>
#include<stack>
#include<queue>
#define MAX 100
#define  NULL -1//这里的空为-1,因为数组的下标为0也是有效区域
using namespace std;
struct node
{
	char data;
	int lchild;
	int rchild;
}Tree1[MAX], Tree2[MAX];
int Create(struct node tree[])
{
	int i,n,root=NULL;//这里一定要赋值为-1,因为树可能为空
	cin >> n;
	int *chick = new int[n + 1];
	fill(chick, chick + n, 0);
	char c,ch1,ch2;
	for (i = 0; i < n; i++)
	{
		cin >> c >> ch1>>ch2;
		tree[i].data = c;
		if (ch1 == '-')		tree[i].lchild = NULL;//如果遇到 - ,则赋值为空,这里为-1
		else
		{
			tree[i].lchild = ch1 - '0';
			chick[tree[i].lchild] = 1;
		}
		if (ch2 == '-')		tree[i].rchild = NULL;
		else
		{
			tree[i].rchild = ch2 - '0';
			chick[tree[i].rchild] = 1;
		}
	}
	for (i = 0; i < n; i++)
	{
		if (!chick[i])
		{
			root = i;
			break;
		}
	}
	delete[] chick;
	return root;
}

bool isomorphis( int r1, int r2)
{
	if (r1 == NULL && r2 == NULL)	return true;

	if ((r1 == NULL && r2 != NULL) || (r1 != NULL && r2 == NULL)) return false;

	if (Tree1[r1].data != Tree2[r2].data) return false;

	if( Tree1[r1].lchild == NULL && Tree2[r2].lchild == NULL)
		return isomorphis(Tree1[r1].lchild,Tree2[r2].lchild)&&
		isomorphis(Tree1[r1].rchild, Tree2[r2].rchild);

	if(Tree1[Tree1[r1].lchild].data == Tree2[Tree2[r2].lchild].data )
		return isomorphis(Tree1[r1].rchild, Tree2[r2].rchild);

	else return isomorphis(Tree1[r1].lchild, Tree2[r2].rchild) && isomorphis(Tree1[r1].rchild, Tree2[r2].lchild);
}

int main()
{
	int r1 = Create(Tree1);
	int r2 = Create(Tree2);
	if (isomorphis(r1, r2)) cout << "Yes" << endl;
	else cout << "No" << endl;
	return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324651748&siteId=291194637