标签:nbsp tree div ptr 树节点 入口 树的遍历 利用 blog
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
bool isSubtree(TreeNode *pRootA,TreeNode *pRootB) {
if(pRootB == NULL) return true;
if(pRootA == NULL) return false;
if(pRootA->val == pRootB->val) {
return isSubtree(pRootA->left,pRootB->left) && isSubtree(pRootA->right,pRootB->right);
}
else
return false;
}
public:
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
{
if(pRoot1 == NULL || pRoot2 == NULL) return false;
return isSubtree(pRoot1,pRoot2)||isSubtree(pRoot1->left,pRoot2)||isSubtree(pRoot1->right,pRoot2);
}
};
本题中HasSubtree函数是程序入口,题目中说了空树不是任意一个树的子结构;isSubtree中RootB为空表示的是B树遍历结束了。
思考:
1.首先需要递归pRoot1树,找到与pRoot2根一样的节点,这需要一个遍历
2.找到相同的根节点后,要判断是否子树,仍需要一个一个遍历对比
树的遍历我们一般就用递归来做,那么根据分析需要两个递归函数如下:
bool IsSubtree(TreeNode*p1, TreeNode *p2)
{
if (!p2)
//此处为p2 == null 是匹配完成的条件
//最开始p2肯定不为NULL,这是在主程序HasSubtree中判断过的。
//递归中,如果p2为空了,则表示上一层的递归中的p2已经匹配完了
return true;
if (!p1)
return false;
if (p1->val != p2->val)
return false;
return IsSubtree(p1->left, p2->left) && IsSubtree(p1->right, p2->right);
}
bool HasSubtree(TreeNode *pRoot1, TreeNode *pRoot2)
{
if(pRoot2 == nullptr)
return false;//题目要求,空树不是任何树的子结构
if(pRoot1 == nullptr)
return false; //显然
//return IsSubtree(pRoot1, pRoot2)||HasSubtree(pRoot1->left, pRoot2)|| HasSubtree(pRoot1->right, pRoot2);
//为了思路清楚,分开谢了,可以利用||或运算直接return
bool flag = IsSubtree(pRoot1, pRoot2);//看看B是不是以A的根为根的子结构
if (!flag)//递归A的左子树,看看做子树中有没有B子结构
flag = HasSubtree(pRoot1->left, pRoot2);
if (!flag)//同上,递归A的右子树
flag = HasSubtree(pRoot1->right, pRoot2);
return flag;
}
其中需要注意的是:
1. 测试用例如果pRoot2为空的话,返回的false而不是我们认为的空树应该是所有树的子树
2. 再判断是否子树的过程中,应该先判断pRoot2是否为空,为空则表明子树的所有节点都比较完了,应该是子树返回True
3. 要养成一个习惯,对任何一个树节点进行访问时,一定要提前检测该节点是否为空
标签:nbsp tree div ptr 树节点 入口 树的遍历 利用 blog
原文地址:http://www.cnblogs.com/dd2hm/p/7294224.html