题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
思路分析
要查找树A中是否存在树B可以分成两步:第一步在树A中找到和B的根节点的值一样的结点R,第二步再判断以树A中以R为根结点的子树是不是包含和树B一样的结构。
第一步在树A中查找与根节点的值一样的点,实际上就是树的遍历,由于递归的代码比较简单,我们采用递归的方式遍历。我们一定要注意边界条件的检查,即检查空指针,当树A和树B为空的时候,定义相应的输出。
第二步是判断树A中以R为根结点的子树是不是和树B具有相同的结构。同样我们也可以用递归的思路来考虑:如果结点R的值和树B的根节点不相同,则以R为根结点的子树和树B结构肯定不同;如果它们的值相同,则递归地判断它们各自的左右结点是不是相同。递归的终止条件是到达了树A或者树B的叶结点。
Java实现
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
boolean result=false;
if(root1!=null && root2!=null){
if(root1.val==root2.val)
result=DoesTree1HaveTree2(root1,root2);
if(!result)
result=HasSubtree(root1.left,root2);
if(!result)
result=HasSubtree(root1.right,root2);
}
return result;
}
//判断一一棵树是否包含另一棵树
boolean DoesTree1HaveTree2(TreeNode root1,TreeNode root2) {
if(root2==null)
return true;
if(root1==null)
return false;
if(root1.val!=root2.val)
return false;
return DoesTree1HaveTree2(root1.left,root2.left)&&DoesTree1HaveTree2(root1.right,root2.right);
}
}
注意上述代码中有多处判断一个指针是不是空,这样做是为了避免试图访问空指针而造成程序崩溃,同时也设置了递归调用的退出条件。在写树的遍历的时候一定要高度警惕,在每一处需要访问地址的时候都要问自己这个地址有没有可能是空,如果是空该怎么处理。