树的同构

树的同构

给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。

图1

图2

现给定两棵树,请你判断它们是否是同构的。

输入格式:

输入给出2棵二叉树树的信息。对于每棵树,首先在一行中给出一个非负整数N (≤ 10),即该树的结点数(此时假设结点从0到N1编号);随后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

 

解题思路

  首先是建树,这里是用静态链表,也就是数组来存放树节点的信息。在建树的过程中用一个数组记录每个树节点的左子树下标位置和右子树下标位置是否出现过,建完树后再遍历一遍找到没有出现过的下标,那么这个下标就是这颗树的根节点。

  这道题判定同构的思路有点复杂。

  • 如果这两颗树的根节点都不存在,也就是说这两颗树都为空,那么这两颗树是同构的。
  • 否则如果其中一颗树存在,而另外一颗树不存在,那么就可以判定这两颗树是不同构的。
  • 否则如果这两颗树都存在:
    • 如果根节点存放的data不相同,那么这两颗树不同构。
    • 否则如果根节点存放的data相同:
      • 如果两颗树的左子树都为空,就判断两颗树的右子树是否同构。
      • 否则如果两颗树的左子树都不为空,并且两颗树的左子树存放的data相同,就分别判断这两颗树的左子树是否同构,右子树是否同构。只有左子树和右子树都同构,这两颗树才同构。
      • 否则就判断第一颗树的左子树和第二颗树的右子树是否同构,以及第一颗树的右子树和第二颗树的左子树是否同构,只有同时满足这两颗树才同构。

  AC代码:

 1 #include <cstdio>
 2 
 3 struct TNode {
 4     char data;
 5     int left;
 6     int right;
 7 }T1[10], T2[10];
 8 
 9 int creatTree(TNode *T);
10 bool isomorphism(int root1, int root2);
11 
12 int main() {
13     int root1 = creatTree(T1);
14     int root2 = creatTree(T2);
15     
16     printf("%s", isomorphism(root1, root2) ? "Yes" : "No");
17     
18     return 0;
19 }
20 
21 int creatTree(TNode *T) {
22     int n;
23     scanf("%d", &n);
24     
25     char ch1, ch2;
26     bool isFind[10] = {false};
27     for (int i = 0; i < n; i++) {
28         scanf("\n%c %c %c", &T[i].data, &ch1, &ch2);
29         
30         if (ch1 == '-') T[i].left = -1;
31         else {
32             T[i].left = ch1 - '0';
33             isFind[T[i].left] = true;
34         }
35         
36         if (ch2 == '-') T[i].right = -1;
37         else {
38             T[i].right = ch2 - '0';
39             isFind[T[i].right] = true;
40         }
41     }
42     
43     int index = 0;
44     while (index < 10 && isFind[index]) {
45         index++;
46     }
47     
48     return n == 0 ? -1 : index;
49 }
50 
51 bool isomorphism(int root1, int root2) {
52     if (root1 == -1 && root2 == -1) {
53         return true;
54     }
55     else if (root1 != -1 && root2 != -1) {
56         if (T1[root1].data == T2[root2].data) {
57             if (T1[root1].left == -1 && T2[root2].left == -1) {
58                 return isomorphism(T1[root1].right, T2[root2].right);
59             }
60             else if (T1[root1].left != -1 && T2[root2].left != -1 && T1[T1[root1].left].data == T2[T2[root2].left].data) {
61                 return isomorphism(T1[root1].left, T2[root2].left) && isomorphism(T1[root1].right, T2[root2].right);
62             }
63             else {
64                 return isomorphism(T1[root1].left, T2[root2].right) && isomorphism(T1[root1].right, T2[root2].left);
65             }
66         }
67         else {
68             return false;
69         }
70     }
71     else {
72         return false;
73     }
74 }

posted @ 2021-05-27 22:47  onlyblues  阅读(897)  评论(0编辑  收藏  举报
Web Analytics