树的子结构

时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M

题目描述

输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
 
知识铺垫:
  先来看下子树和子结构的概念
    子树:只要包含了一个节点,就得包含这个节点下的所有节点
    子结构:包含了一个节点,可以只取左子树或右子树,或者不取,强调结构上的一致
  (可参考:https://blog.csdn.net/wushuomin/article/details/79943737)
 思路:
  一颗大树A,一颗小树B,首先判断A的根节点是否与B的根节点相同,不相同,就依次去A根节点的左子树、右子树上查找,如果存在(假设A中与B的根节点相等的节点为D),此时需要判断的就是D的左子树、右子树是否与B的根节点的左子树、右子树相同节点结构,终止条件:如果B先访问到头了,即小树B先达到NULL,说明B就是A的子结构,如果大树A达到NULL,说明就不是A的子结构。
 
  采用递归的方式
/*
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 != NULL && pRoot2 != NULL)
        {
            if(pRoot1->val == pRoot2->val)
            {
                //该根节点作为起点判断是否包含pRoot2
                result = judgeSubTree(pRoot1,pRoot2);
            }
            //如果没有找到,就去该节点的左子树中找
            if(!result)
            {
                result = HasSubtree(pRoot1->left,pRoot2);
            }
            //如果还没有找到,就去该节点的右子树中找
            if(!result)
            {
                result = HasSubtree(pRoot1->right,pRoot2);
            }
             
        }
        return result;
    }
private:
    bool judgeSubTree(TreeNode *node1,TreeNode *node2)
    {
        if(node2 == NULL)
            return true;
        if(node1 == NULL)
            return false;
         if(node1->val != node2->val)
         {
             return false;
         }
        return judgeSubTree(node1->left,node2->left)
            && judgeSubTree(node1->right,node2->right);
    }
};
在judgeSubTree函数中对node1->val 与node2->val判断是否相等是有必要的,应为该函数是一个递归函数,下面递归调用的时候,还是要判断传进去的两个节点的值是否相等
另一种写法:
/*
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)
    {
        if(pRoot1 == NULL || pRoot2 == NULL)
        {
            return false;
        }
        return judeSubTree(pRoot1,pRoot2) 
            || judeSubTree(pRoot1->left,pRoot2)
            ||judeSubTree(pRoot1->right,pRoot2);
    }
    bool judeSubTree(TreeNode* node1,TreeNode * node2)
    {
        if(node2 == NULL)
            return true;
        if(node1 == NULL)
            return false;
        if(node1->val != node2->val)
            return judeSubTree(node1->left,node2) || 
            judeSubTree(node1->right,node2);
        return judeSubTree(node1->left,node2->left)&&
            judeSubTree(node1->right,node2->right);
    }
};

子结构包含与子树,子树会要求更加严格,不仅结构相同,节点的值也要相同,只需要对其值判断相等,不能就直接返回false即可

判断是否为子树:

/*
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)
    {
        if(pRoot1 == NULL || pRoot2 == NULL)
        {
            return false;
        }
        return judeSubTree(pRoot1,pRoot2) 
            || judeSubTree(pRoot1->left,pRoot2)
            ||judeSubTree(pRoot1->right,pRoot2);
    }
    bool judeSubTree(TreeNode* node1,TreeNode * node2)
    {
        if(node2 == NULL)
            return true;
        if(node1 == NULL)
            return false;
        if(node1->val != node2->val)
            return false;
        return judeSubTree(node1->left,node2->left)&&
            judeSubTree(node1->right,node2->right);
    }
};
原文地址:https://www.cnblogs.com/whiteBear/p/12523524.html