树的子结构和拓扑相同的子树

之前做了剑指offer的“树的子结构”和牛客网算法课“拓扑相同的子树”,发觉这其中还是有些微妙的地方需要注意的,总结如下:

树的子结构和树的子树问题:

子树的意思是包含了一个结点,就得包含这个结点下的所有节点,一棵大小为n的二叉树有n个子树,就是分别以每个结点为根的子树。子结构的意思是包含了一个结点,可以只取左子树或者右子树,或者都不取。
如下图,二叉树2是二叉树1的子树也是子结构,但是二叉树3只是二叉树1的子结构但不是子树。

这里写图片描述

也就是说判断一个二叉树是否为另一二叉树的子树的时候,需要所搜索到叶子节点,即从根节点及其左右子树的节点都要相同。而判断一个二叉树是否为另一颗二叉树的子结构的时候,不一定需要到达叶子节点,其对应结构节点相同即可。

题目一:剑指offer

输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

class Solution {
public:
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
        bool result=false;
        if(pRoot1!=NULL&&pRoot2!=NULL)
        {
            if(pRoot1->val==pRoot2->val)
            {
                result=isInclude(pRoot1,pRoot2);
            }
            if(!result) result=isInclude(pRoot1->left,pRoot2);
            if(!result) result=isInclude(pRoot1->right,pRoot2);
        }
        return result;
    }
private:
    bool isInclude(TreeNode* pRoot1,TreeNode* pRoot2)
    {
        if(pRoot2==NULL) return true;//子树先到达叶子节点返回true
        if(pRoot1==NULL) return false;//父树先到达叶子节点返回false
        if(pRoot1->val!=pRoot2->val) return false;

        return isInclude(pRoot1->left,pRoot2->left)&&isInclude(pRoot1->right,pRoot2->right);//分别搜索左子树和右子树
    }
};

题目二:牛客网算法课(树的子树)

对于两棵彼此独立的二叉树A和B,请编写一个高效算法,检查A中是否存在一棵子树与B树的拓扑结构完全相同。给定两棵二叉树的头结点A和B,请返回一个bool值,代表A中是否存在一棵同构于B的子树。

class IdenticalTree {
public:
    bool chkIdentical(TreeNode* A, TreeNode* B) {
        // write code here
       bool res=false;
       if(A!=NULL&&B!=NULL)
       {
         if(A->val==B->val)
           res=IsAHasB(A,B);
         if(!res)
           res=chkIdentical(A->left,B);
         if(!res)
           res=chkIdentical(A->right,B);
       }
       return res;
    }
    bool IsAHasB(TreeNode* A,TreeNode* B)//需要一直遍历到叶子节点
    {
        if(A==NULL&&B!=NULL) return false;
        if(A!=NULL&&B==NULL) return false;//当任何一个树先到达叶子节点,返回false
        if(A==NULL&&B==NULL) return true;//同时到达叶子节点,返回true
        if(A->val!=B->val) return false;
        return IsAHasB(A->left,B->left)&&IsAHasB(A->right,B->right);
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值