題目:輸入兩棵二叉樹A和B,判斷B是不是A的子結構。
二叉樹結點的定義如下:
struct BinaryTreeNode { int m_nValue; BinaryTreeNode *m_pLeft; BinaryTreeNode *m_pRight; };
例如圖中的兩棵二叉樹,由於A中有一部分子樹的結構和B是一樣的,因此B是A的子結構。
要查找樹A中是否存在和樹B結構一樣的子樹,可以分成兩步:
- 第一步在樹A中找到和B的根節點的值一樣的結點R;
- 第二步再判斷樹A中以R為根結點的子樹是不是包含和樹B一樣的結構。
第一步在樹A中查找與根結點的值一樣的結點,這實際上就是樹的遍歷。遞歸調用HasSubTree遍歷二叉樹A。如果發現某一結點的值和樹B的頭結點的值相同,則調用DoesTreeHavaTree2,做第二步判斷。
第二步是判斷樹A中以R為根結點的子樹是不是和樹B具有相同的結構。
核心代碼:
1 bool HasSubtree(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2) 2 { 3 bool result = false; 4 5 if(pRoot1 != NULL && pRoot2 != NULL) 6 { 7 if(pRoot1->m_nValue == pRoot2->m_nValue) 8 result = DoesTree1HaveTree2(pRoot1, pRoot2); 9 if(!result) 10 result = HasSubtree(pRoot1->m_pLeft, pRoot2); 11 if(!result) 12 result = HasSubtree(pRoot1->m_pRight, pRoot2); 13 } 14 15 return result; 16 } 17 18 bool DoesTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2) 19 { 20 if(pRoot2 == NULL) 21 return true; 22 23 if(pRoot1 == NULL) 24 return false; 25 26 if(pRoot1->m_nValue != pRoot2->m_nValue) 27 return false; 28 29 return DoesTree1HaveTree2(pRoot1->m_pLeft, pRoot2->m_pLeft) && 30 DoesTree1HaveTree2(pRoot1->m_pRight, pRoot2->m_pRight); 31 }
注意在使用指針的時候一定要注意邊界條件,即檢查空指針。當樹A或樹B為空的時候,定義相應的輸出。如果沒有檢查並做相應的處理,程序非常容易崩潰。