给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。
图1
图2
现给定两棵树,请你判断它们是否是同构的。
输入格式:
输入给出2棵二叉树树的信息。对于每棵树,首先在一行中给出一个非负整数N (≤),即该树的结点数(此时假设结点从0到N−1编号);随后N行,第i行对应编号第i个结点,给出该结点中存储的1个英文大写字母、其左孩子结点的编号、右孩子结点的编号。如果孩子结点为空,则在相应位置上给出“-”。给出的数据间用一个空格分隔。注意:题目保证每个结点中存储的字母是不同的。
输出格式:
如果两棵树是同构的,输出“Yes”,否则输出“No”。
输入样例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
方法一用链式解决,刚开始学的时候用的能够AC, 然后复习的时候发现 方法二 用数组也能做, 未能提交,但是过了样例,如下。
方法一 :
#include<stdlib.h>
#include <string.h>
#include<stdio.h>
#include<malloc.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define INFEASIBLE -2
#define NULL 0
int n1 = 0, n2 = 0;
typedef int Status;
typedef char TElemType;
typedef struct BiTNode
{
TElemType data;
int left, right;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
void ConnectBiTreeLeft(BiTNode *root, BiTNode T[])
{
if(root->left != -1)
{
root->lchild = &T[root->left];
ConnectBiTreeLeft(root->lchild, T);
}
else
return;
}
void ConnectBiTreeRight(BiTNode *root, BiTNode T[])
{
if(root->right != -1)
{
root->rchild = &T[root->right];
ConnectBiTreeRight(root->rchild, T);
}
else
return;
}
BiTree SearchRoot(BiTNode a[], int n)
{
int temp[15] = {0};
for(int i = 0; i < n; ++i)
{
if(a[i].left != -1)
temp[a[i].left] = 1;
if(a[i].right != -1)
temp[a[i].right] = 1;
}
for(int i = 0; i < n; ++i)
if(temp[i] == 0)
return &a[i];
}
void InPut(BiTNode Node[], int n)
{
char l, r;
//printf("InPut****************n = %d\n", n);
for(int i = 0; i < n; ++i)
{
getchar();
scanf("%c %c %c", &Node[i].data, &l, &r);
// printf("InPut%c %c %c\n", Node[i].data, l, r);
if(l != '-')
Node[i].left = l - '0';
else
{
Node[i].left = -1;
Node[i].lchild = NULL;
}
if(r != '-')
Node[i].right = r - '0';
else
{
Node[i].right = -1;
Node[i].rchild = NULL;
}
}
//printf("InPut****************\n");
}
Status PreOrderTraverse(BiTree T, Status (*visit)(char))
{
if(T)
{
if((*visit)(T->data))
if(PreOrderTraverse(T->lchild, (*visit)))
if(PreOrderTraverse(T->rchild, (*visit)))
return OK;
else
return ERROR;
}
else
return OK;
}
Status Print(char e)
{
printf("%c", e);
return OK;
}
Status Compare(BiTree T1, BiTree T2)
{
if(T1 == NULL || T2 == NULL)
return T1 == T2;
if(T1->data == T2->data)
{
return (Compare(T1->lchild, T2->lchild) && Compare(T1->rchild, T2->rchild)) || (Compare(T1->lchild, T2->rchild) && Compare(T1->rchild, T2->lchild));
}
return FALSE;
}
int main()
{
BiTree T1 = NULL, T2 = NULL;
BiTNode a1[15], a2[15];
char b1[15], b2[15];
int n1, n2;
scanf("%d", &n1);
InPut(a1, n1);
scanf("%d", &n2);
InPut(a2, n2);
// printf("0****************\n");
if(n1 != n2)
{
printf("No");
return 0;
}
else
{
// printf("1****************\n");
for(int i = 0; i < n1; ++i)
{
// printf("2****************\n");
ConnectBiTreeLeft(&a1[i], a1);
ConnectBiTreeRight(&a1[i], a1);
ConnectBiTreeLeft(&a2[i], a2);
ConnectBiTreeRight(&a2[i], a2);
}
//printf("3****************\n");
for(int i = 0; i < n1; ++i)
{
T1 = SearchRoot(a1, n1);
T2 = SearchRoot(a2, n1);
}
// printf("4**************%c", T1->data);
// PreOrderTraverse(T1, Print);
// printf("\n");
// printf("5**************%c\n", T2->data);
// PreOrderTraverse(T2, Print);
if(!Compare(T1, T2))
printf("No");
else
printf("Yes");
}
}
方法二:
#include<bits/stdc++.h>
typedef struct BiTNode
{
char data;
int left, right;
}BiTNode;
typedef BiTNode *Node_Ptr;
typedef BiTNode *BiTree;
int root[100];
BiTree T1, T2;
int BuildTree(BiTree &T)
{
int n;
scanf("%d", &n);
// getchar();
memset(root, 0, sizeof(root));
T = (BiTree)malloc(sizeof(BiTNode) * (n + 1));
for(int i = 0; i < n; ++i)
{
getchar();
char left, right;
scanf("%c %c %c", &T[i].data, &left, &right);
T[i].left = left - '0';
T[i].right = right - '0';
if(T[i].left < 0 || T[i].left > 9)
T[i].left = -1;
if(T[i].right < 0 || T[i].right > 9)
T[i].right = -1;
if(T[i].left != -1)
root[T[i].left] = 1;
if(T[i].right != -1)
root[T[i].right] = 1;
// printf("%c %d %d\n", T[i].data, T[i].left, T[i].right);
}
for(int i = 0; i < n; ++i)
if(root[i] == 0)
return i;
return -1;
}
int Isostructuralism(int root1, int root2)
{
if(root1 == root2 && root1 == -1)
return 1;
else
{
return (T1[root1].data == T2[root2].data) && (Isostructuralism(T1[root1].left, T2[root2].left) || Isostructuralism(T1[root1].left, T2[root2].right) || Isostructuralism(T1[root1].right, T2[root2].left) || Isostructuralism(T1[root1].right, T2[root2].right));
}
return 0;
}
int main()
{
int n, root1, root2;
root1 = BuildTree(T1);
root2 = BuildTree(T2);
int result = Isostructuralism(root1, root2);
if(result == 1)
printf("Yes\n");
else
printf("No\n");
}