劍指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;注意考慮特殊用例,邊界問題,模擬思考遞歸的執行過程。