题目:输入两个二叉树A和B,判断B是否是A的子结构。如下图所是,B树是A树的子结构:
我们约定空树不是任意一个树的子结构。
一般二叉树的判断问题都用递归方法来解决。递归方法首先要确定方法的参数,以及递归结构。
二叉树的结构为:
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
}
这里涉及到两个递归函数:
-
主递归函数,判断root2是否是root1的子结构:
bool HasSubtree(TreeNode* root1, TreeNode* root2) -
递归判断root1是否包含root2(从根节点开始就要包含):
bool DoesTree1HaveTree2(TreeNode* root1, TreeNode* root2)。
判断步骤:
- 空树不是任何树的子结构,所以不管是哪个是空树,HasSubtree都直接返回false。
- 以下三种情况都可以认定root2是root1的子结构:
从根节点开始,root2就是root1的子结构(用DoesTree1HaveTree2函数判断)
root2是root1左子树的子结构
root2是root1右子树的子结构 - 对于DoesTree1HaveTree2函数
如果root2为空,t2遍历结束,说明是子树,返回true
如果root1为空,空子树无法包含子树,所以返回false
如果root1和root2的值不一样,直接返回false
他们的左子树和右子树都互相包含。
代码如下:
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
{
if (pRoot1 == nullptr || pRoot2 == nullptr) {
return false;
}
return DoesTree1HaveTree2(pRoot1, pRoot2) ||
HasSubtree(pRoot1->left, pRoot2) ||
HasSubtree(pRoot1->right, pRoot2);
}
bool DoesTree1HaveTree2(TreeNode* t1, TreeNode* t2) {
if (t2 == nullptr) {//t2遍历结束,说明是子树
// 必须先判断,出现t1和t2同时为空,这时也返回true
return true;
}
if (t1 == nullptr) {//空子树无法包含子树,所以是false
return false;
}
if (t1->val != t2->val) {
return false;
}
return DoesTree1HaveTree2(t1->left, t2->left) &&
DoesTree1HaveTree2(t1->right, t2->right);
}