#数据结构与算法学习笔记#PTA9:同构二叉树(JAVA)

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));
		}

		
	}
}


猜你喜欢

转载自blog.csdn.net/qq_20304723/article/details/79817035