輸入某二叉樹的前序遍歷和中序遍歷的結果,重建該二叉樹
題目:輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。
思路:
先序遍歷的第一個元素為根節點,在中序遍歷中找到這個根節點,從而可以將中序遍歷分為左右兩個部分,左邊部分為左子樹的中序遍歷,右邊部分為右子樹的中序遍歷,進而也可以將先序遍歷除第一個元素以外的剩餘部分分為兩個部分,第一個部分為左子樹的先序遍歷,第二個部分為右子樹的先序遍歷。
由上述分析結果,可以遞迴呼叫構建函式,根據左子樹、右子樹的先序、中序遍歷重建左、右子樹。
完整程式碼及其測試用例實現:
#include<iostream> #include <exception>//異常處理類 using namespace std; //二叉樹節點定義 struct BinaryTreeNode { int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; }; //列印樹節點 void PrintTreeNode(BinaryTreeNode* pNode) { if (pNode != NULL) { cout << "value of this root node is: " << pNode->m_nValue << endl; if (pNode->m_pLeft != NULL) { cout << "value of its left child is: " << pNode->m_pLeft->m_nValue << endl; } else { cout << "left child is null. " << endl; } if (pNode->m_pRight != NULL) { cout << "value of its right child is: " << pNode->m_pRight->m_nValue << endl; } else { cout << "right child is null. " << endl; } } else { cout << "this root node is null. " << endl; } cout << endl; } //遍歷樹 void PrintTree(BinaryTreeNode* pRoot) { PrintTreeNode(pRoot); if (pRoot != NULL) { if (pRoot->m_pLeft != NULL) { PrintTree(pRoot->m_pLeft); } if (pRoot->m_pRight != NULL) { PrintTree(pRoot->m_pRight); } } } //銷燬樹 void DestroyTree(BinaryTreeNode* pRoot) { if (pRoot != NULL) { BinaryTreeNode* pLeft = pRoot->m_pLeft; BinaryTreeNode* pRight = pRoot->m_pRight; delete pRoot; pRoot = NULL; DestroyTree(pLeft); DestroyTree(pRight); } } //重建二叉樹 BinaryTreeNode* ConstructCore(int* startPreorder, int* endPreorder,int* startInorder, int* endInorder) { // 前序遍歷序列的第一個數字是根結點的值 int rootValue = startPreorder[0]; BinaryTreeNode* root = new BinaryTreeNode(); root->m_nValue = rootValue; root->m_pLeft = NULL; root->m_pRight = NULL; if (startPreorder == endPreorder) { if (startInorder == endInorder && *startPreorder == *startInorder) { return root; } else { throw std::exception("Invalid input."); } } // 在中序遍歷中找到根結點的值 int* rootInorder = startInorder; while (rootInorder <= endInorder && *rootInorder != rootValue) { ++rootInorder; } if (rootInorder == endInorder && *rootInorder != rootValue) { throw std::exception("Invalid input."); } int leftLength = rootInorder - startInorder; int* leftPreorderEnd = startPreorder + leftLength; if (leftLength > 0) { // 構建左子樹 root->m_pLeft = ConstructCore(startPreorder + 1, leftPreorderEnd, startInorder, rootInorder - 1); } if (leftLength < endPreorder - startPreorder) { // 構建右子樹 root->m_pRight = ConstructCore(leftPreorderEnd + 1, endPreorder, rootInorder + 1, endInorder); } return root; } BinaryTreeNode* Construct(int* preorder, int* inorder, int length) { if (preorder == NULL || inorder == NULL || length <= 0) { return NULL; } return ConstructCore(preorder, preorder + length - 1, inorder, inorder + length - 1); } // ====================測試程式碼==================== void Test(char* testName, int* preorder, int* inorder, int length) { if (testName != NULL) { cout << testName << " begins:" << endl; } cout << "The preorder sequence is:" ; for (int i = 0; i < length; ++i) { cout << preorder[i] << " "; } cout <<endl; cout << "The inorder sequence is:"; for (int i = 0; i < length; ++i) { cout << inorder[i] << " "; } cout << endl; try { BinaryTreeNode* root = Construct(preorder, inorder, length); PrintTree(root); DestroyTree(root); } catch (std::exception& exception) { cout << " Invalid Input."<<endl; } } void Test1() { // 普通二叉樹 // 1 // / \ // 2 3 // / / \ // 4 5 6 // \ / // 7 8 const int length = 8; int preorder[length] = { 1, 2, 4, 7, 3, 5, 6, 8 }; int inorder[length] = { 4, 7, 2, 1, 5, 3, 8, 6 }; Test("Test1", preorder, inorder, length); } void Test2() { // 所有結點都沒有右子結點 // 1 // / // 2 // / // 3 // / // 4 // / // 5 const int length = 5; int preorder[length] = { 1, 2, 3, 4, 5 }; int inorder[length] = { 5, 4, 3, 2, 1 }; Test("Test2", preorder, inorder, length); } void Test3() { // 所有結點都沒有左子結點 // 1 // \ // 2 // \ // 3 // \ // 4 // \ // 5 const int length = 5; int preorder[length] = { 1, 2, 3, 4, 5 }; int inorder[length] = { 1, 2, 3, 4, 5 }; Test("Test3", preorder, inorder, length); } void Test4() { // 樹中只有一個結點 const int length = 1; int preorder[length] = { 1 }; int inorder[length] = { 1 }; Test("Test4", preorder, inorder, length); } void Test5() { // 完全二叉樹 // 1 // / \ // 2 3 // / \ / \ // 4 5 6 7 const int length = 7; int preorder[length] = { 1, 2, 4, 5, 3, 6, 7 }; int inorder[length] = { 4, 2, 5, 1, 6, 3, 7 }; Test("Test5", preorder, inorder, length); } void Test6() { // 輸入空指標 Test("Test6", NULL, NULL, 0); } void Test7() { // 輸入的兩個序列不匹配 const int length = 7; int preorder[length] = { 1, 2, 4, 5, 3, 6, 7 }; int inorder[length] = { 4, 2, 8, 1, 6, 3, 7 }; Test("Test7: for unmatched input", preorder, inorder, length); } int main() { Test1(); Test2(); Test3(); Test4(); Test5(); Test6(); Test7(); system("pause"); return 0; }
執行結果:
Test1 begins:
The preorder sequence is:1 2 4 7 3 5 6 8
The inorder sequence is:4 7 2 1 5 3 8 6
value of this root node is: 1
value of its left child is: 2
value of its right child is: 3
value of this root node is: 2
value of its left child is: 4
right child is null.
value of this root node is: 4
left child is null.
value of its right child is: 7
value of this root node is: 7
left child is null.
right child is null.
value of this root node is: 3
value of its left child is: 5
value of its right child is: 6
value of this root node is: 5
left child is null.
right child is null.
value of this root node is: 6
value of its left child is: 8
right child is null.
value of this root node is: 8
left child is null.
right child is null.
Test2 begins:
The preorder sequence is:1 2 3 4 5
The inorder sequence is:5 4 3 2 1
value of this root node is: 1
value of its left child is: 2
right child is null.
value of this root node is: 2
value of its left child is: 3
right child is null.
value of this root node is: 3
value of its left child is: 4
right child is null.
value of this root node is: 4
value of its left child is: 5
right child is null.
value of this root node is: 5
left child is null.
right child is null.
Test3 begins:
The preorder sequence is:1 2 3 4 5
The inorder sequence is:1 2 3 4 5
value of this root node is: 1
left child is null.
value of its right child is: 2
value of this root node is: 2
left child is null.
value of its right child is: 3
value of this root node is: 3
left child is null.
value of its right child is: 4
value of this root node is: 4
left child is null.
value of its right child is: 5
value of this root node is: 5
left child is null.
right child is null.
Test4 begins:
The preorder sequence is:1
The inorder sequence is:1
value of this root node is: 1
left child is null.
right child is null.
Test5 begins:
The preorder sequence is:1 2 4 5 3 6 7
The inorder sequence is:4 2 5 1 6 3 7
value of this root node is: 1
value of its left child is: 2
value of its right child is: 3
value of this root node is: 2
value of its left child is: 4
value of its right child is: 5
value of this root node is: 4
left child is null.
right child is null.
value of this root node is: 5
left child is null.
right child is null.
value of this root node is: 3
value of its left child is: 6
value of its right child is: 7
value of this root node is: 6
left child is null.
right child is null.
value of this root node is: 7
left child is null.
right child is null.
Test6 begins:
The preorder sequence is:
The inorder sequence is:
this root node is null.
Test7: for unmatched input begins:
The preorder sequence is:1 2 4 5 3 6 7
The inorder sequence is:4 2 8 1 6 3 7
Invalid Input.
請按任意鍵繼續. . .