题目:输入两颗二叉树A和B,判断B是不是A的子结构。
重点:(1)递归思想的使用!递归思想在做题过程中经常出现。(2)在写遍历树的代码的时候一定要高度警惕,在每一处需要访问地址的时候都要判断这个地址是否为nullptr。
思路:判断树A中是否包含树B中的子结构,可以先比较根节点,如果根节点相同,再分别比较左节点和右节点是否相同,如果相同,则返回true,说明树B是树A的子结构。如果根节点不同,则继续遍历树A,并与B比较。
我的问题:如果A和B的根节点不同,比较A的左节点,如果A的左节点相同,比较A的左节点的左节点与B的左节点,如果A的左节点的左节点不同与B的左节点不同,则将A的左节点的左节点与B的根节点比较。那么问题来了,A子树的右节点与B进行比较的过程是怎么进行的???(数据结构小白啊啊啊)
针对上述问题:代码中,HasSubtree(pRoot1->left,pRoot)和HasSubtree(pRoot1->left,pRoot)是同时进行的,但具体怎么操作呢??待解决。。。其实还是对递归和二叉树不熟悉
跟书上的代码略有不同,书上多写了一个Equal函数用于比较两个节点的值是否相等。在Equal函数中,节点中值的类型为double,在判断两个节点的值是否相等时,不能直接写pRoot1->val == pRoot2->val,因为在计算机内表示小数时(float和double型)都有误差,判断两个小数是否相等,只能判断它们之差的绝对值是不是在一个很小的范围内。如果两个数相差很小,就可以认为他们相等。
代码:
class Solution {
public:
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
{
bool result = false;
if(pRoot1 !=nullptr && pRoot2 !=nullptr)
{
//先比较两个二叉树的根节点
if(pRoot1->val == pRoot2->val)
//如果相同,以这个根节点为起点,判断Tree1是否包含Tree2
result = DoesTree1HaveTree2(pRoot1,pRoot2);
//如果找不到,以Tree1左子节点为起点判断是否包含Tree2
if(!result)
result = HasSubtree(pRoot1->left,pRoot2);
//如果找不到,再以Tree1左子节点为起点判断是否包含Tree2
if(!result)
result = HasSubtree(pRoot1->right,pRoot2);
}
return result;
}
bool DoesTree1HaveTree2(TreeNode* pRoot1, TreeNode* pRoot2)
{
//如果tree2都遍历完了且Tree1中包含该结构,则返回true
if(pRoot2 == NULL)
return true;
//如果Tree1已经遍历完了仍然没有找到与Tree2相同的子结构,返回false
if(pRoot1 == nullptr)
return false;
//如果根节点的值不同,直接返回false
if(pRoot1->val != pRoot2->val)
return false;
return DoesTree1HaveTree2(pRoot1->left,pRoot2->left) && DoesTree1HaveTree2(pRoot1->right,pRoot2->right);
}
};
版权声明:本文为baidu_32936911原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。