// face questions 26: sub-tree // Title: two binary inputs A and B, B is judged not substructure A's. #include <cstdio> struct BinaryTreeNode { Double m_dbValue; BinaryTreeNode * m_pLeft; BinaryTreeNode * m_pRight; }; BOOL DoesTree1HaveTree2 (BinaryTreeNode pRoot1 *, * BinaryTreeNode pRoot2); BOOL Equal ( Double num1, Double num2); BOOL HasSubtree (BinaryTreeNode * pRoot1, * BinaryTreeNode pRoot2) { IF (pRoot1 == == nullptr a || pRoot2 nullptr a) return to false ; BOOL Result = to false ; IF (Equal (pRoot1-> m_dbValue, pRoot2-> m_dbValue)) // if the root node B to match, continues to match other nodes Result = DoesTree1HaveTree2 (pRoot1, pRoot2); IF (! Result ) Result = HasSubtree (pRoot1-> m_pLeft, pRoot2); // find a match in the tree A left node IF ! ( Result) Result = HasSubtree (pRoot1-> m_pRight, pRoot2); // node A tree for a match on the right return Result ; } BOOL DoesTree1HaveTree2 (BinaryTreeNode pRoot1 *, * BinaryTreeNode pRoot2) { if (pRoot2 == nullptr) return true; if (pRoot1 == nullptr) //A树叶节点为空 return false; if (!Equal(pRoot1->m_dbValue, pRoot2->m_dbValue)) return false; return DoesTree1HaveTree2(pRoot1->m_pLeft, pRoot2->m_pLeft) && DoesTree1HaveTree2(pRoot1->m_pRight, pRoot2->m_pRight); } bool Equal(double num1, double num2) { if (num1 - num2 < 0.0000001 && num1 - num2 > -0.0000001) return true; else return false; }
// ====================辅助测试代码==================== BinaryTreeNode* CreateBinaryTreeNode(double dbValue) { BinaryTreeNode* pNode = new BinaryTreeNode(); pNode->m_dbValue = dbValue; pNode->m_pLeft = nullptr; pNode->m_pRight = nullptr; return pNode; } void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight) { if (pParent != nullptr) { pParent->m_pLeft = pLeft; pParent->m_pRight = pRight; } } void DestroyTree(BinaryTreeNode* pRoot) { if (pRoot != nullptr) { BinaryTreeNode* pLeft = pRoot->m_pLeft; BinaryTreeNode* pRight = pRoot->m_pRight; delete pRoot; pRoot = nullptr; DestroyTree(pLeft); DestroyTree(pRight); } } // ====================测试代码==================== void Test(const charTestName *, * pRoot1 BinaryTreeNode, BinaryTreeNode * pRoot2, BOOL expected) { IF (HasSubtree (pRoot1, pRoot2) == expected) the printf ( " % S passed \ n-. " , TestName); the else the printf ( " % S failed \. n- " , TestName); } // tree node contains bifurcation, B is a sub-tree of the tree a // 88 // / \ / \ // 8792 // / \ // 92 / / / \ // 4 7 void Test1() { BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8); BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8); BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(7); BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(9); BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(2); BinaryTreeNode* pNodeA6 = CreateBinaryTreeNode(4); BinaryTreeNode* pNodeA7 = CreateBinaryTreeNode(7); ConnectTreeNodes(pNodeA1, pNodeA2, pNodeA3); ConnectTreeNodes(pNodeA2, pNodeA4, pNodeA5); ConnectTreeNodes(pNodeA5, pNodeA6, pNodeA7); BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8); BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9); BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(2); ConnectTreeNodes(pNodeB1, pNodeB2, pNodeB3); Test("Test1", pNodeA1, pNodeB1, true); DestroyTree(pNodeA1); DestroyTree(pNodeB1); } // 树中结点含有分叉,树B不是树A的子结构 // 8 8 // / \ / \ // 8 7 9 2 // / \ // 9 3 // / \ // 4 7 void Test2() { BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8); BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8); BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(7); BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(9); BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(3); BinaryTreeNode* pNodeA6 = CreateBinaryTreeNode(4); BinaryTreeNode* pNodeA7 = CreateBinaryTreeNode(7); ConnectTreeNodes(pNodeA1, pNodeA2, pNodeA3); ConnectTreeNodes(pNodeA2, pNodeA4, pNodeA5); ConnectTreeNodes(pNodeA5, pNodeA6, pNodeA7); BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8); BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9); BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(2); ConnectTreeNodes (pNodeB1, pNodeB2, pNodeB3); the Test ( " Test2 " , pNodeA1, pNodeB1, to false ); DestroyTree (pNodeA1); DestroyTree (pNodeB1); } // tree nodes only the left child node, the tree is a B tree A substructures // . 8. 8 // / / // . 8. 9 // / / // . 9 2 // / // 2 // / // . 5 void the Test3 () { BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8); BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8); BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(9); BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(2); BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(5); ConnectTreeNodes(pNodeA1, pNodeA2, nullptr); ConnectTreeNodes(pNodeA2, pNodeA3, nullptr); ConnectTreeNodes(pNodeA3, pNodeA4, nullptr); ConnectTreeNodes(pNodeA4, pNodeA5, nullptr); BinaryTreeNode* PNodeB1 = CreateBinaryTreeNode ( . 8 ); BinaryTreeNode * pNodeB2 = CreateBinaryTreeNode ( . 9 ); BinaryTreeNode * pNodeB3 = CreateBinaryTreeNode ( 2 ); ConnectTreeNodes (pNodeB1, pNodeB2, nullptr a); ConnectTreeNodes (pNodeB2, pNodeB3, nullptr a); the Test ( " the Test3 " , pNodeA1, pNodeB1, to true ); DestroyTree (pNodeA1); DestroyTree (pNodeB1); } // tree nodes only substructure left child node a is not a tree tree B // 88 // / / // 8 9 // / / // 9 3 // / // 2 // / // 5 void Test4() { BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8); BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8); BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(9); BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(2); BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(5); ConnectTreeNodes(pNodeA1, pNodeA2, nullptr); ConnectTreeNodes(pNodeA2, pNodeA3, nullptr); ConnectTreeNodes(pNodeA3, pNodeA4, nullptr); ConnectTreeNodes(pNodeA4, pNodeA5, nullptr); BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8); BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9); BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(3); ConnectTreeNodes(pNodeB1, pNodeB2, nullptr); ConnectTreeNodes(pNodeB2, pNodeB3, nullptr); Test("Test4", PNodeA1, pNodeB1, to false ); DestroyTree (pNodeA1); DestroyTree (pNodeB1); } // tree nodes only right child node, B is a sub-tree of the tree A // 88 // \ \ // 8 . 9 // \ \ // . 9 2 // \ // 2 // \ // . 5 void Test5 should be conducted () { BinaryTreeNode * pNodeA1 CreateBinaryTreeNode = ( . 8 ); BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8); BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(9); BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(2); BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(5); ConnectTreeNodes(pNodeA1, nullptr, pNodeA2); ConnectTreeNodes(pNodeA2, nullptr, pNodeA3); ConnectTreeNodes(pNodeA3, nullptr, pNodeA4); ConnectTreeNodes(pNodeA4, nullptr, pNodeA5); BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8); BinaryTreeNode* PNodeB2 = CreateBinaryTreeNode ( . 9 ); BinaryTreeNode * pNodeB3 = CreateBinaryTreeNode ( 2 ); ConnectTreeNodes (pNodeB1, nullptr a, pNodeB2); ConnectTreeNodes (pNodeB2, nullptr a, pNodeB3); the Test ( " Test5 should be conducted " , pNodeA1, pNodeB1, to true ); DestroyTree ( pNodeA1); DestroyTree (pNodeB1); } // tree node a, only the right-child node of the sub-structure, a is not a tree tree B // 88 // \ \ // 89 // \ / \ // 9 3 2 // \ // 2 // \ // 5 void Test6() { BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8); BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8); BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(9); BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(2); BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(5); ConnectTreeNodes(pNodeA1, nullptr, pNodeA2); ConnectTreeNodes(pNodeA2, nullptr, pNodeA3); ConnectTreeNodes(pNodeA3, nullptr, pNodeA4); ConnectTreeNodes(pNodeA4, nullptr, pNodeA5); BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8); BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9); BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(3); BinaryTreeNode* pNodeB4 = CreateBinaryTreeNode(2); ConnectTreeNodes(pNodeB1, nullptr, pNodeB2); ConnectTreeNodes(pNodeB2, pNodeB3, pNodeB4); Test("Test6", pNodeA1, pNodeB1, false); DestroyTree(pNodeA1); DestroyTree(pNodeB1); } // 树A为空树 void Test7() { BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8); BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9); BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(3); BinaryTreeNode* pNodeB4 = CreateBinaryTreeNode(2); ConnectTreeNodes(pNodeB1, nullptr, pNodeB2); ConnectTreeNodes(pNodeB2, pNodeB3, pNodeB4); Test("Test7", nullptr, pNodeB1, false); DestroyTree(pNodeB1); } // 树B为空树 void Test8() { BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8); BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(9); BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(3); BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(2); ConnectTreeNodes(pNodeA1, nullptr, pNodeA2); ConnectTreeNodes(pNodeA2, pNodeA3, pNodeA4); Test("Test8", PNodeA1, nullptr a, to false ); DestroyTree (pNodeA1); } // Tree Tree A and B are empty void test9 () { the Test ( " test9 " , nullptr a, nullptr a, to false ); } int main ( int argc, char * the argv []) { Test1 (); Test2 (); the Test3 (); Test4 (); Test5 should be conducted (); Test6 (); TEST7 (); test8 (); test9 (); return 0 ; }
Analysis: Recursive simple.
/* 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) { if (pRoot1 == nullptr || pRoot2 == nullptr) return false; bool result = false; if (pRoot1->val == pRoot2->val) result = DoesTree1HaveTree2(pRoot1, pRoot2); if (!result) result = HasSubtree(pRoot1->left, pRoot2); if (!result) result = HasSubtree(pRoot1->right, pRoot2); return result; } bool DoesTree1HaveTree2(TreeNode* pRoot1, TreeNode* pRoot2) { if (pRoot2 == nullptr) return true; if (pRoot1 == nullptr) return false; if (pRoot1->val != pRoot2->val) return false; return DoesTree1HaveTree2(pRoot1->left, pRoot2->left) && DoesTree1HaveTree2(pRoot1->right, pRoot2->right); } };