剑指offer—树的子结构
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
博客中代码均在牛客C++11(clang++ 3.9)中通过
要判断B是不是A的子结构分为两步:
- 第一步是在A树中找B树的根节点,找不到就说明不是
- 如果找到了,就比较他们的左右子树是否具有相同的结构
所以,就需要遍历树,这里使用递归的方式:
代码如下:
/*
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(nullptr == pRoot1 || nullptr == pRoot2)
return false;
bool ret = false;
if(pRoot1->val == pRoot2->val)
ret = DoesTree1HaveTree2(pRoot1,pRoot2);
if(!ret)
ret = HasSubtree(pRoot1->left,pRoot2);
if(!ret)
ret = HasSubtree(pRoot1->right,pRoot2);
return ret;
}
private:
bool DoesTree1HaveTree2(TreeNode* pRoot1, TreeNode* pRoot2)
{
if(nullptr == pRoot2)
return true;
if(nullptr == pRoot1)
return false;
if(pRoot1->val != pRoot2->val)
return false;
return DoesTree1HaveTree2(pRoot1->left,pRoot2->left) && DoesTree1HaveTree2(pRoot1->right,pRoot2->right);
}
};
在《剑指offer》书中判断两个结点的值是否相等时使用了自定义函数Equal,是因为那道题目中给出的val为double类型,在计算机中表示小数时都有误差,所以判断小数相等的依据只能是判断它们差的绝对值是否在一个很小的范围内,这里附上Equal函数的代码:
bool Equal(double num1, double num2)
{
if((num1-num2>-0.0000001) && (num1-num2)<0.0000001)
return true;
else
return false;
}