1、问题描述
给定两棵树 T1 和 T2。如果 T1 可以通过若干次左右孩子互换变成 T2,则我们称两棵树是“同构”的。现给定两棵树,判 断它们是否是同构。
图1:

图2:
图1为同构,图2不是同构。
2、问题要求
第一行是一个非负整数 N1,表示第 1 棵树的结点数;随后 N 行,依次对应二叉树的 N 个结点(假设结点从 0 到 N− 1 编号),每行有三项,分别是 1 个英文大写字母、其左孩子结点的编号、右孩子结点的编号。如果孩子结点为空,则在相应位置上给出“-”。给出的数据间用一个空格分隔。接着一行是一个非负整数 N2,表示第 2 棵树的结点数;随后 N 行同上描述一样,依次对应二叉树的 N 个结点。
3、解决问题
(1)数据结构设计
首先定义一个顺序存储的二叉树类型,用于存放数据和其左右子树的编号。然后定义一个式存储的二叉树类型,用于存放数据和其左右子树。
代码实现:
struct Node {
char date;
int left;
int right;
}T1[10110], T2[10110];
typedef struct BiTNode {
char date;
struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;
(2)完整代码
1. #include<iostream>
2. #include<string>
3.
4. using namespace std;
5.
6. struct Node {
7. char date;
8. int left;
9. int right;
10. }T1[10110], T2[10110];
11.
12. typedef struct BiTNode {
13. char date;
14. struct BiTNode* lchild, * rchild;
15. }BiTNode, * BiTree;
16.
17. struct Tup {
18. char date;
19. string left;
20. string right;
21. int tage;
22. }tup[10110];
23.
24. int CreatData(Tup tup[]) {
25. int n;
26. char ch;
27. cin >> n;
28. ch = getchar();
29. for (int i = 0; i < n; i++) {
30. cin >> tup[i].date >> tup[i].left >> tup[i].right;
31. tup[i].tage = 0;
32. ch = getchar();
33. }
34. for (int i = 0; i < n; i++) {
35. if (tup[i].left != "-")
36. tup[atoi(tup[i].left.c_str())].tage = 1;
37. if (tup[i].right != "-")
38. tup[atoi(tup[i].right.c_str())].tage = 1;
39. }
40. return n;
41. }
42.
43. int CreatTree_S(struct Node T[], Tup tup[], int n) {
44. int R = 0;
45. if (!n)
46. return -1;
47. for (int i = 0; i < n; i++) {
48. T[i].date = tup[i].date;
49. if (tup[i].left == "-")
50. T[i].left = -1;
51. else {
52. T[i].left = atoi(tup[i].left.c_str());
53. R -= T[i].left;
54. }
55. if (tup[i].right == "-")
56. T[i].right = -1;
57. else {
58. T[i].right = atoi(tup[i].right.c_str());
59. R -= T[i].right;
60. }
61. R += i;
62. }
63. return R;
64. }
65.
66. int CreatTree_L(BiTree& T, string e) {
67. if (e == "-") {
68. T = NULL;
69. }
70. else {
71. T = new BiTNode;
72. T->date = tup[atoi(e.c_str())].date;
73. CreatTree_L(T->lchild, tup[atoi(e.c_str())].left);
74. CreatTree_L(T->rchild, tup[atoi(e.c_str())].right);
75. }
76. return 1;
77. }
78.
79. int judge(int a, int b)
80. {
81. if (a == -1 && b == -1)
82. return 1;
83. else if ((a != -1 && b == -1) || (a == -1 && b != -1))
84. return 0;
85. else if (T1[a].date != T2[b].date)
86. return 0;
87. else if (judge(T1[a].left, T2[b].left) && judge(T1[a].right,
T2[b].right))
88. return 1;
89. else if (judge(T1[a].left, T2[b].right) && judge(T1[a].left,
T2[b].right))
90. return 1;
91. else
92. return 0;
93. }
94.
95. int Depth(BiTree T) {
96. int m, n;
97. if (T == NULL)
98. return 0;
99. else {
100. m = Depth(T->lchild);
101. n = Depth(T->rchild);
102. if (m > n)
103. return m + 1;
104. else
105. return n + 1;
106. }
107. }
108.
109. int main() {
110. int root, root2, dp1, dp2, n;
111. BiTree T3, T4;
112. n = CreatData(tup);
113. root = CreatTree_S(T1, tup, n);
114. CreatTree_L(T3, to_string(root));
115. n = CreatData(tup);
116. root2 = CreatTree_S(T2, tup, n);
117. CreatTree_L(T4, to_string(root2));
118. if (judge(root, root2))
119. cout << "Yes" << endl;
120. else
121. cout << "No" << endl;
122. dp1 = Depth(T3);
123. dp2 = Depth(T4);
124. cout << dp1 << endl << dp2 << endl;
125. return 0;
126. }