剑指offer26. 树的子结构(一棵二叉树b是不是被二叉树a包含)P148
题目:输入两棵二叉树A和B,判断B是不是A的子结构。
递归结束条件:如果rootp为空,说明对比的子树已经找完了,此时不管root是不是空,都可以返回true(主调函数提前判断了rootp一开始就为空的情况),如果在rootp不为空的情况下root为空,说明这里肯定不对,因为子树还没有对比完,母树已经没了,返回false;
逻辑判断:如果root.val==rootp.val
,那么此时有两种情况:
- 这个root节点是子结构的一部分,我们要判断roop的左右子树是不是也分别包含在root的左右子树中(这里用的是&&,因为要同时满足):
HasSubtree(root -> m_pLeft, rootp -> m_pLeft)
&& HasSubtree(root -> m_pRight, rootp -> m_pRight
- 如果不包含这个节点(虽然两个根节点一样,但是在后面的递归过程出现两个结构不等的情况),我们就不能取这个root,所以要看root的左右子树是不是存在包含子结构的 (这里用的是||,因为不管左右子树哪个包含,只要出现就行)
HasSubtree(root -> m_pLeft, rootp)
|| HasSubtree(root -> m_pRight, rootp);
两种情况一种成立就可以,所以中间用||连接 (这里会容易忽略第二种情况)
回到开始,如果root.val != rootp.val
,也就是进入那个else判断,这时就和上面的情况2一样了,直接返回左右子树和rootp比较的结果:
HasSubtree(root -> m_pLeft, rootp)
|| HasSubtree(root -> m_pRight, rootp);
// ---------------主递归函数---------------------------------
bool HasSubtree(BinaryTreeNode *root, BinaryTreeNode *rootp) {
if (rootp == NULL) return true;
if (root == NULL) return false;
if (equal(root -> m_dbValue, rootp -> m_dbValue)) { // 比较浮点数
return (HasSubtree(root -> m_pLeft, rootp -> m_pLeft) // 情况1
&& HasSubtree(root -> m_pRight, rootp -> m_pRight))
|| HasSubtree(root -> m_pLeft, rootp) // 情况2
|| HasSubtree(root -> m_pRight, rootp);
} else {
return HasSubtree(root -> m_pLeft, rootp) // 情况2
|| HasSubtree(root -> m_pRight, rootp);
}
}
bool has(BinaryTreeNode *root, BinaryTreeNode *rootp) { // 主调函数,root是母树
if (rootp == NULL || root == NULL) return false; //默认两棵树任一个是空,返回false
return HasSubtree(root, rootp); // 递归判断
}