剑指Offer——面试题7:重建二叉树
Posted cxc1357
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指Offer——面试题7:重建二叉树相关的知识,希望对你有一定的参考价值。
题目:输入某二叉树的前序遍历和中序遍历结果,重建该二叉树。(假设输入的前序和中序遍历结果中都不含重复数字)
1 #include "BinaryTree.h" 2 #include <stdexcept> 3 #include <iostream> 4 #include <cstdio> 5 #include <cstdlib> 6 7 BinaryTreeNode* ConstructCore(int* startPreorder, int* endPreorder, int* startInorder, int* endInorder); 8 9 BinaryTreeNode* Construct(int* preorder, int* inorder, int length) 10 { 11 if(preorder == nullptr || inorder == nullptr || length <= 0) 12 return nullptr; 13 14 return ConstructCore(preorder, preorder + length - 1, 15 inorder, inorder + length - 1); 16 } 17 18 BinaryTreeNode* ConstructCore 19 ( 20 int* startPreorder, int* endPreorder, 21 int* startInorder, int* endInorder 22 ) 23 { 24 // 前序遍历序列的第一个数字是根结点的值 25 int rootValue = startPreorder[0]; 26 BinaryTreeNode* root = new BinaryTreeNode(); 27 root->m_nValue = rootValue; 28 root->m_pLeft = root->m_pRight = nullptr; 29 30 if(startPreorder == endPreorder) 31 { 32 if(startInorder == endInorder && *startPreorder == *startInorder) 33 return root; 34 else 35 throw -1; 36 } 37 38 // 在中序遍历中找到根结点的值 39 int* rootInorder = startInorder; 40 while(rootInorder <= endInorder && *rootInorder != rootValue) 41 ++ rootInorder; 42 43 if(rootInorder == endInorder && *rootInorder != rootValue) 44 throw -1; 45 46 int leftLength = rootInorder - startInorder; 47 int* leftPreorderEnd = startPreorder + leftLength; 48 if(leftLength > 0) 49 { 50 // 构建左子树 51 root->m_pLeft = ConstructCore(startPreorder + 1, leftPreorderEnd, 52 startInorder, rootInorder - 1); 53 } 54 if(leftLength < endPreorder - startPreorder) 55 { 56 // 构建右子树 57 root->m_pRight = ConstructCore(leftPreorderEnd + 1, endPreorder, 58 rootInorder + 1, endInorder); 59 } 60 61 return root; 62 } 63 64 // ====================测试代码==================== 65 void Test(char* testName, int* preorder, int* inorder, int length) 66 { 67 if(testName != nullptr) 68 printf("%s begins: ", testName); 69 70 printf("The preorder sequence is: "); 71 for(int i = 0; i < length; ++ i) 72 printf("%d ", preorder[i]); 73 printf(" "); 74 75 printf("The inorder sequence is: "); 76 for(int i = 0; i < length; ++ i) 77 printf("%d ", inorder[i]); 78 printf(" "); 79 80 try 81 { 82 BinaryTreeNode* root = Construct(preorder, inorder, length); 83 PrintTree(root); 84 DestroyTree(root); 85 } 86 catch(int d) 87 { 88 printf("Invalid Input. "); 89 } 90 } 91 92 // 普通二叉树 93 // 1 94 // / 95 // 2 3 96 // / / 97 // 4 5 6 98 // / 99 // 7 8 100 void Test1() 101 { 102 const int length = 8; 103 int preorder[length] = {1, 2, 4, 7, 3, 5, 6, 8}; 104 int inorder[length] = {4, 7, 2, 1, 5, 3, 8, 6}; 105 106 Test("Test1", preorder, inorder, length); 107 } 108 109 // 所有结点都没有右子结点 110 // 1 111 // / 112 // 2 113 // / 114 // 3 115 // / 116 // 4 117 // / 118 // 5 119 void Test2() 120 { 121 const int length = 5; 122 int preorder[length] = {1, 2, 3, 4, 5}; 123 int inorder[length] = {5, 4, 3, 2, 1}; 124 125 Test("Test2", preorder, inorder, length); 126 } 127 128 // 所有结点都没有左子结点 129 // 1 130 // 131 // 2 132 // 133 // 3 134 // 135 // 4 136 // 137 // 5 138 void Test3() 139 { 140 const int length = 5; 141 int preorder[length] = {1, 2, 3, 4, 5}; 142 int inorder[length] = {1, 2, 3, 4, 5}; 143 144 Test("Test3", preorder, inorder, length); 145 } 146 147 // 树中只有一个结点 148 void Test4() 149 { 150 const int length = 1; 151 int preorder[length] = {1}; 152 int inorder[length] = {1}; 153 154 Test("Test4", preorder, inorder, length); 155 } 156 157 // 完全二叉树 158 // 1 159 // / 160 // 2 3 161 // / / 162 // 4 5 6 7 163 void Test5() 164 { 165 const int length = 7; 166 int preorder[length] = {1, 2, 4, 5, 3, 6, 7}; 167 int inorder[length] = {4, 2, 5, 1, 6, 3, 7}; 168 169 Test("Test5", preorder, inorder, length); 170 } 171 172 // 输入空指针 173 void Test6() 174 { 175 Test("Test6", nullptr, nullptr, 0); 176 } 177 178 // 输入的两个序列不匹配 179 void Test7() 180 { 181 const int length = 7; 182 int preorder[length] = {1, 2, 4, 5, 3, 6, 7}; 183 int inorder[length] = {4, 2, 8, 1, 6, 3, 7}; 184 Test("Test7: for unmatched input", preorder, inorder, length); 185 } 186 187 int main(int argc, char* argv[]) 188 { 189 Test1(); 190 Test2(); 191 Test3(); 192 Test4(); 193 Test5(); 194 Test6(); 195 Test7(); 196 return 0; 197 }
- 构建二叉树的两个函数:Construct()、ConstructCore()
- Construct()面向输入数据(用户),ConstructCore()面向处理数据(程序)
- 通过Construct()调用ConstructCore(),对用户隐藏了具体实现
BinaryTree.cpp
1 #include <cstdio> 2 #include "BinaryTree.h" 3 4 BinaryTreeNode* CreateBinaryTreeNode(int value) 5 { 6 BinaryTreeNode* pNode = new BinaryTreeNode(); 7 pNode->m_nValue = value; 8 pNode->m_pLeft = nullptr; 9 pNode->m_pRight = nullptr; 10 11 return pNode; 12 } 13 14 void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight) 15 { 16 if(pParent != nullptr) 17 { 18 pParent->m_pLeft = pLeft; 19 pParent->m_pRight = pRight; 20 } 21 } 22 23 void PrintTreeNode(const BinaryTreeNode* pNode) 24 { 25 if(pNode != nullptr) 26 { 27 printf("value of this node is: %d ", pNode->m_nValue); 28 29 if(pNode->m_pLeft != nullptr) 30 printf("value of its left child is: %d. ", pNode->m_pLeft->m_nValue); 31 else 32 printf("left child is nullptr. "); 33 34 if(pNode->m_pRight != nullptr) 35 printf("value of its right child is: %d. ", pNode->m_pRight->m_nValue); 36 else 37 printf("right child is nullptr. "); 38 } 39 else 40 { 41 printf("this node is nullptr. "); 42 } 43 44 printf(" "); 45 } 46 47 void PrintTree(const BinaryTreeNode* pRoot) 48 { 49 PrintTreeNode(pRoot); 50 51 if(pRoot != nullptr) 52 { 53 if(pRoot->m_pLeft != nullptr) 54 PrintTree(pRoot->m_pLeft); 55 56 if(pRoot->m_pRight != nullptr) 57 PrintTree(pRoot->m_pRight); 58 } 59 } 60 61 void DestroyTree(BinaryTreeNode* pRoot) 62 { 63 if(pRoot != nullptr) 64 { 65 BinaryTreeNode* pLeft = pRoot->m_pLeft; 66 BinaryTreeNode* pRight = pRoot->m_pRight; 67 68 delete pRoot; 69 pRoot = nullptr; 70 71 DestroyTree(pLeft); 72 DestroyTree(pRight); 73 } 74 }
BinaryTree.h
1 struct BinaryTreeNode 2 { 3 int m_nValue; 4 BinaryTreeNode* m_pLeft; 5 BinaryTreeNode* m_pRight; 6 }; 7 8 BinaryTreeNode* CreateBinaryTreeNode(int value); 9 void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight); 10 void PrintTreeNode(const BinaryTreeNode* pNode); 11 void PrintTree(const BinaryTreeNode* pRoot); 12 void DestroyTree(BinaryTreeNode* pRoot);
以上是关于剑指Offer——面试题7:重建二叉树的主要内容,如果未能解决你的问题,请参考以下文章