解法一:递归
递归判断子树是否同构,直接比较原树或者交换左右子树后再比较。边界条件为遍历到叶子结点。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class Node {
char val;
Node left;
Node right;
public Node() {
}
}
public class Main {
public static void main(String[] args) throws IOException {
// 读入数据
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
final int lenA = Integer.parseInt(reader.readLine());
Node rootA = buildTree(reader, lenA);
final int lenB = Integer.parseInt(reader.readLine());
Node rootB = buildTree(reader, lenB);
if (lenA != lenB) {
System.out.println("No");
return;
}
if (dfs(rootA, rootB)) {
System.out.println("Yes");
} else {
System.out.println("No");
}
}
/**
* 建树
*
* @param reader 输入
* @param len 结点数
* @return 树的根结点
* @throws IOException
*/
private static Node buildTree(BufferedReader reader, int len) throws IOException {
boolean[] hasFather = new boolean[len];
String[] strs;
char val;
Node left, right;
int number;
Node[] tree = new Node[len];
for (int i = 0; i < len; ++i) {
tree[i] = new Node();
}
for (int i = 0; i < len; ++i) {
strs = reader.readLine().split(" ");
val = strs[0].charAt(0);
if (strs[1].charAt(0) == '-') {
left = null;
} else {
number = Integer.parseInt(strs[1]);
left = tree[number];
hasFather[number] = true;
}
if (strs[2].charAt(0) == '-') {
right = null;
} else {
number = Integer.parseInt(strs[2]);
right = tree[number];
hasFather[number] = true;
}
tree[i].val = val;
tree[i].left = left;
tree[i].right = right;
}
Node root = null;
for (int i = 0; i < len; ++i) {
if (!hasFather[i]) {
root = tree[i];
break;
}
}
return root;
}
private static boolean dfs(Node rootA, Node rootB) {
if (rootA == null && rootB == null) {
return true;
}
if (rootA == null || rootB == null) {
return false;
}
boolean isLeafA = (rootA.left == null) && (rootA.right == null);
boolean isLeafB = (rootB.left == null) && (rootB.right == null);
if (isLeafA && isLeafB) { // 都是叶子结点
return rootA.val == rootB.val;
} else if (isLeafA || isLeafB) { // 其中一个是叶子结点
return false;
} else { // 递归判断子树是否同构
return (dfs(rootA.left, rootB.left) && dfs(rootA.right, rootB.right)) ||
(dfs(rootA.left, rootB.right) && dfs(rootA.right, rootB.left));
}
}
}