题目:输入两棵二叉树A和B,判断B是不是A的子结构。
算法分析:
要查找树A中是否存在和树B结构一样的子树,我们可以分为两步,第一步:在树A中找到和树B的根节点的值一样的节点R,第二步再判断树A中以R为根节点的子树是不是包含和树B一样的结构。
以上面两棵树为例来详细分析这个过程。首先我们试着在树A中找到值为8(树B的根节点的值)得节点。从树A的根节点开始遍历,我们发现它的根节点的值就是8.接着我们就去判断树A的根节点线面的子树是不是含有和树B一样的结构。在树A中,根节点的左子节点的值是8,而树B的根节点的左子节点是9,对应的两个节点不同。
因此我们仍然需要遍历树A,接着查找值为8的节点。我们在树的第二层找到了一个值为8的节点,然后进行第二步判断,即判断这个节点下面的子树是否含有和树B一样结构的子树。于是我们遍历这个节点下面的子树,先后得到两个子节点9和2,这和树B的结构完全相同。此时我们在树A中找到了一个和树B的结构一样的子树,因此树B是树A的子结构。
程序代码:
/**************************************************************
* Copyright (c) 2016,
* All rights reserved.
* 版 本 号:v1.0
* 题目描述:树的子结构
* 题目:输入一个二叉树A和B,判断B是不是A的子结构。
* 输入描述:
* 程序输出:
* 问题分析:
* 算法描述:要查找树A中是否存在和树B结构一样的子树,我们可以分为两步:第一步:在树A中找到和树B的根节点的值一样的节点R,
* 第二步再判断树A中以R为根节点的子树是不是包含和树B一样的结构。以上面两棵树为例来详细分析这个过程。
* 首先我们试着在树A中找到值为8(树B的根节点的值)得节点。从树A的根节点开始遍历,我们发现它的根节点的值就是8.
* 接着我们就去判断树A的根节点线面的子树是不是含有和树B一样的结构。在树A中,根节点的左子节点的值是8,而树B的根节点的左子节点是9,
* 对应的两个节点不同。因此我们仍然需要遍历树A,接着查找值为8的节点。我们在树的第二层找到了一个值为8的节点,
* 然后进行第二步判断,即判断这个节点下面的子树是否含有和树B一样结构的子树。于是我们遍历这个节点下面的子树,
* 先后得到两个子节点9和2,这和树B的结构完全相同。此时我们在树A中找到了一个和树B的结构一样的子树,因此树B是树A的子结构。
* 完成日期:2016-09-01
***************************************************************/
package org.marsguo.offerproject;
class TreeNode{
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val){
this.val = val;
}
}
class Solution{
public boolean HasSubtree(TreeNode root1,TreeNode root2){
boolean result =false;
/*当Tree1和Tree2都不为0时才进行比较,否则直接返回false*/
if(root1 != null && root2 != null){
if(root1.val == root2.val){ //如果找到了对应Tree2根节点的节点
result = DoesTreeHaveTree2(root1,root2); //以这个根节点为起点判断是否包含Tree2
}
if(!result){ //如果没有找到,则去root的左子节点当做起点,去判断是否包含Tree2
result = HasSubtree(root1.left, root2);
}
if(!result){ //如果没有找到,则去root的右子节点当做起点,去判断是否包含Tree2
result = HasSubtree(root1.right,root2);
}
}
return result; //返回结果
}
public boolean DoesTreeHaveTree2(TreeNode root1,TreeNode root2){
if(root2 == null){ //如果Tree2已经遍历完了都能对应的上,返回true
return true;
}
if(root1 == null && root2 != null){ //如果Tree1已经遍历完了Tree2却没有遍历完,返回false
return false;
}
if(root1.val != root2.val) { //如果其中一个节点没有对应上,返回false
return false;
}
/*如果根节点对应上了,那么就分别去子节点里匹配*/
return DoesTreeHaveTree2(root1.left, root2.left)&&DoesTreeHaveTree2(root1.right, root2.right);
}
}
public class HasSubTree {
public static void main(String[] args){
/*
1
/ \
2 3
/ \ \
4 5 6
*/
TreeNode r1 = new TreeNode(1);
TreeNode r2 = new TreeNode(2);
TreeNode r3 = new TreeNode(3);
TreeNode r4 = new TreeNode(4);
TreeNode r5 = new TreeNode(5);
TreeNode r6 = new TreeNode(6);
}
}