剑指offer:148页(高质量的代码)
题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构
/*
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(pRoot1->val == pRoot2->val)//B(树2)有可能是A(树1)的自子结构,进一步判断
{
result = DoesTree1HaveTree2(pRoot1,pRoot2);
}
//搜索树的子节点,看是否有节点与B的根节点相等;此处利用递归的方法对树A进行遍历
//先搜索左节点,利用result 表示树A当前节点是否有树B的子结构,否则向下搜索
if(!result)
result = HasSubtree(pRoot1->left,pRoot2);
//后搜索右节点
if(!result)
result = HasSubtree(pRoot1->right,pRoot2);
}
return result;
}
//树A当前节点pRoot1是否存在树B pRoot2
bool DoesTree1HaveTree2(TreeNode* pRoot1, TreeNode* pRoot2)
{
//pRoot2为空,表示前面的对应节点都相等,所以返回true;
if(pRoot2 == nullptr)
return true;
//pRoot1为空,表示在pRoot2(树B的某个节点)还有值时,树A已经没有对应的值了,所以返回false;
if(pRoot1 == nullptr)
return false;
if(pRoot1->val == pRoot2->val)
{
//搜索树A当前节点的左子节点与树B当前节点的左子节点, //搜索树A当前节点的右子节点与树B当前节点的右子节点 //只有左子树相等后再判断右子数
return DoesTree1HaveTree2(pRoot1->left,pRoot2->left) && DoesTree1HaveTree2(pRoot1->right,pRoot2->right);
}
else
{
//树A、树B的当前节点不相等则返回false;
return false;
}
}
};
总结:代码鲁棒性的考查,本题含有大量指针操作,必须考虑指针是否为空;两次递归,在遍历树A的过程中遍历树B;注意考虑特殊用例,边界问题,模拟思考递归的执行过程。