树的子结构
题目:输入两棵二叉树A和B,判断B是不是A的子结构。
第一步:在树A中找到和树B的根节点的值一样的节点R;
第二步:判断树A中以R为根节点的子树是不是包含和树B一样的结构。
这里,我们通过输入树的前序遍历和中序遍历构建二叉树,然后判断树的子结构,代码如下:
package jianzhioffer;
import java.util.Scanner;
/**
* 剑指Offer:树的子结构
*/
public class HasSubtree {
//定义二叉树节点
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode righe = null;
public TreeNode(int val) {
this.val = val;
}
}
//根据前序遍历和中序遍历重建二叉树,并返回二叉树的根节点
public BinaryTreeNode reConstructBinaryTree(int[] pre, int[] in) {
if (pre.length == 0 || in.length == 0) {
return null;
}
BinaryTreeNode node = binaryTreeReconstruct(pre, 0, pre.length - 1, in, 0, in.length - 1);
return node;
}
//使用递归重构二叉树
private BinaryTreeNode binaryTreeReconstruct(int[] pre, int startPre, int endPre, int[] in, int startIn, int endIn) {
if (startIn > endIn || startPre > endPre)
return null;
BinaryTreeNode node = new BinaryTreeNode(pre[startPre]);
for (int i = startIn; i <= endIn; i++) {
if (in[i] == pre[startPre]) {
node.left = binaryTreeReconstruct(pre, startPre + 1, startPre + i - startIn, in, startIn, i - 1);
node.right = binaryTreeReconstruct(pre, i - startIn + startPre + 1, endPre, in, i + 1, endIn);
}
}
return node;
}
/**
* 在树1中查找与根节点的值一样的节点
*
* @param root1
* @param root2
* @return
*/
private static boolean hasSubtree(BinaryTreeNode root1, BinaryTreeNode root2) {
boolean result = false;
if (root1 != null && root2 != null) {
if (Equal(root1.val, root2.val))
result = DoesTree1HaveTree2(root1, root2);
if (!result)
result = hasSubtree(root1.left, root2);
if (!result)
result = hasSubtree(root1.right, root2);
}
return result;
}
/**
* 判断树1中以R为根节点的子树是不是和树2具有相同的结构
*
* @param root1
* @param root2
* @return
*/
private static boolean DoesTree1HaveTree2(BinaryTreeNode root1, BinaryTreeNode root2) {
if (root2 == null)
return true;
if (root1 == null&&root2!=null)
return false;
if (!Equal(root1.val, root2.val))
return false;
return DoesTree1HaveTree2(root1.left, root2.left) && DoesTree1HaveTree2(root1.right, root2.right);
}
/**
* 判断两个数是否相等
* 当计算机表示小数时,会存在一定范围的误差,如果其绝对值小于某一阈值,则认为它们相等
*
* @param num1
* @param num2
* @return
*/
private static boolean Equal(int num1, int num2) {
if (num1 - num2 > -0.0000001 && num1 - num2 < 0.0000001)
return true;
else
return false;
}
//创建两个整型数组
public static int[] nodeProcess(String[] array) {
int[] num = new int[array.length];
for (int i = 0; i < array.length; i++) {
num[i] = Integer.parseInt(array[i]);
}
return num;
}
/**
* 主函数
* 输入四行
* 前两行分别表示树1的前序遍历和中序遍历
* 后两行分别表示树2的前序遍历和中序遍历
*
* @param args
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
String[] preStr_1 = sc.nextLine().split(",");
String[] inStr_1 = sc.nextLine().split(",");
int[] pre_1 = nodeProcess(preStr_1);
int[] in_1 = nodeProcess(inStr_1);
String[] preStr_2 = sc.nextLine().split(",");
String[] inStr_2 = sc.nextLine().split(",");
int[] pre_2 = nodeProcess(preStr_2);
int[] in_2 = nodeProcess(inStr_2);
HasSubtree hst = new HasSubtree();
BinaryTreeNode root1 = hst.reConstructBinaryTree(pre_1, in_1);
BinaryTreeNode root2 = hst.reConstructBinaryTree(pre_2, in_2);
boolean result = hasSubtree(root1, root2);
System.out.println(result);
}
sc.close();
}
}