剑指offer-26 树的子结构

题目:输入两棵二叉树A和B,判断B是不是A的子结构.

image.png

思路:

第一步 : 在树A找到和树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 {
    //root1 => A    root2 => B
    //相同根节点情况下, 判断树A的子树是否含有跟树B一样的树结构
    public boolean HasSubtree(TreeNode root1,TreeNode root2) {
        //树为空
        if(root1 == null || root2 == null){
            return false;
        }
        return isSubtreeWithRoot(root1, root2) || HasSubtree(root1.left, root2) || HasSubtree(root1.right , root2);//递归,判断根节点 
    }
    
    //判断B是不是A的子结构 root1 => A    root2 => B
    //判断树A和树B根节点值是否相等,   根节点的左右节点是否相等
    private boolean isSubtreeWithRoot(TreeNode root1 , TreeNode root2){
        //root1和root2判断空不能颠倒顺序
        if(root2 == null) return true;
        if(root1 == null) return false;
        if(root1.val != root2.val)  return false;
        return isSubtreeWithRoot(root1.left, root2.left) && isSubtreeWithRoot(root1.right , root2.right);//递归判断子节点是否相等
    }
}

C++代码:

struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};

class Solution {
public:
    //代码注释见上
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
        bool result = false;
      	//先行条件:根节点为非空指针
        if(pRoot1 != nullptr && pRoot2 != nullptr){
          	//判断根节点值是否相等
            if(Equal(pRoot1->val, pRoot2->val))
                result = DoesTreeHaveTree(pRoot1, pRoot2);
          	//判断左右节点是否相等
            if(!result)
                result = HasSubtree(pRoot1->left,pRoot2);
            if(!result)
                result = HasSubtree(pRoot1->right, pRoot2);
        }
        return result;
    }
  
  	//相同根节点情况下, 判断树A的子树是否含有跟树B一样的树结构
    // pRoot1 => A    pRoot2 => B
  	//递归终止条件:到达树A或树B叶子节点
    bool DoesTreeHaveTree(TreeNode* pRoot1, TreeNode* pRoot2){
      //空指针处理,注意先后顺序
        if(pRoot2 == nullptr) return true;
        if(pRoot1 == nullptr) return false;
        if(pRoot1->val != pRoot2->val) return false;
      	//返回值判断当前节点的左右子节点
        return DoesTreeHaveTree(pRoot1->left,pRoot2->left) && DoesTreeHaveTree(pRoot1->right,pRoot2->right);
    }
  
    //小数有误差, 不用等号判断相等,|num1  - num2 | < 0.0000001即为两个数相等
    bool Equal(double num1,double num2){
        if((num1 - num2 > -0.0000001) && (num1 - num2 < 0.0000001))
            return true;
        else
            return false;
    }
};
原文地址:https://www.cnblogs.com/fightingcode/p/10821479.html