2018.3.30
一段时间没用JAVA,担心手生了,这题特地用java来写一下。
题目注意事项在注释中已经写得比较清楚,这里应该要注意一下JAVA输入的注意事项,具体可以看一下这个链接:
https://www.cnblogs.com/zhrb/p/6347738.html?utm_source=itdadao&utm_medium=referral
主要注意两点:1.不要混用nextLine、next、nextInt方法,可以用nextLine整行读入后再进行处理;2.不要多次创建Scanner类,可以将创建过程转移到类外。这道题是不写不知道,写了之后会对以上两点有深刻体会。
原题:
给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。
现给定两棵树,请你判断它们是否是同构的。
输入格式:
输入给出2棵二叉树树的信息。对于每棵树,首先在一行中给出一个非负整数N (≤10),即该树的结点数(此时假设结点从0到N−1编号);随后N行,第i行对应编号第i个结点,给出该结点中存储的1个英文大写字母、其左孩子结点的编号、右孩子结点的编号。如果孩子结点为空,则在相应位置上给出“-”。给出的数据间用一个空格分隔。注意:题目保证每个结点中存储的字母是不同的。
输出格式:
如果两棵树是同构的,输出“Yes”,否则输出“No”。
以下是本题JAVA实现:
import java.util.ArrayList; import java.util.Scanner; //二叉树结点类 class TreeNode { char value; int leftChild; int rightChild; } //上传PTA需要将类名改为Main public class Isomorphism_BinTree { private static ArrayList<TreeNode> tree1 = new ArrayList<TreeNode>(); private static ArrayList<TreeNode> tree2 = new ArrayList<TreeNode>(); //private static final int MAX = 10; private static Scanner indata = new Scanner(System.in); public static void main(String[] args) { int root1 = BuildTree(tree1); int root2 = BuildTree(tree2); if (IsIsomorphism(root1, root2)) { System.out.println("Yes"); } else { System.out.println("No"); } indata.close(); } // 创建一棵树,返回其根节点下标 private static int BuildTree(ArrayList<TreeNode> tree) { //Scanner indata = new Scanner(System.in); //结点数 int num=Integer.parseInt(indata.nextLine()); //判断空树 if(num == 0){ return -1; } int[] check = new int[num]; //检查根节点数组 for (int i = 0; i < num; i++) { TreeNode treeNode = new TreeNode(); //读数值 String[] node=indata.nextLine().split(" "); //值 treeNode.value=node[0].charAt(0); //左子结点 char left=node[1].charAt(0); if(left != '-'){ treeNode.leftChild = left-'0'; check[left-'0'] = 1; }else{ treeNode.leftChild = -1; } //右子结点 char right=node[2].charAt(0); if(right != '-'){ treeNode.rightChild = right-'0'; check[right-'0'] = 1; }else{ treeNode.rightChild = -1; } tree.add(treeNode); } //根节点 int root = 0; for(int i = 0;i<num;i++){ if(check[i] == 0){ root = i; break; } } return root; } // 判断俩树是否同构 private static boolean IsIsomorphism(int root1, int root2) { //两树均空,同构 if(root1 == -1 && root2 == -1){ return true; //有一棵空一棵不空,不同构 }else if((root1 == -1)&&(root2 != -1) || (root1 != -1)&&(root2 == -1)){ return false; //根节点值不想等,不同构 }else if(tree1.get(root1).value != tree2.get(root2).value){ return false; //左子树均空,递归查右子树 }else if((tree1.get(root1).leftChild == -1) && (tree2.get(root2).leftChild == -1)){ return IsIsomorphism(tree1.get(root1).rightChild, tree2.get(root2).rightChild); //右子树均空,递归查左子树 }else if((tree1.get(root1).rightChild == -1) && (tree2.get(root2).rightChild == -1)){ return IsIsomorphism(tree1.get(root1).leftChild, tree2.get(root2).leftChild); } //左右子树均不空,并且左子树根节点值相等,递归查左子树和右子树,返回(左子树同构&&右子树同构) if(((tree1.get(root1).leftChild != -1) && (tree2.get(root2).leftChild != -1)) && (tree1.get(tree1.get(root1).leftChild).value) == (tree2.get(tree2.get(root2).leftChild).value)){ return (IsIsomorphism(tree1.get(root1).leftChild, tree2.get(root2).leftChild) && IsIsomorphism(tree1.get(root1).rightChild, tree2.get(root2).rightChild)); } //左右子树均不空,并且左子树根节点值不相等,递归查左右子树是否同构 else{ return(IsIsomorphism(tree1.get(root1).leftChild, tree2.get(root2).rightChild) && IsIsomorphism(tree1.get(root1).rightChild, tree2.get(root2).leftChild)); } } }