输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果都不含重复的数字。
二叉树定义如下:
1
2 3 4 5 6 |
struct TreeNode
{ int val; TreeNode* left; TreeNode* right; }; |
在二叉树的前序遍历中,第一个数字总是树的根结点的值。但在中序遍历中,根结点的值在序列的中间,左子树的结点的值位于根结点的值得左边,而右子树节点的值位于根结点的值的右边。因此我们需要扫描中先序遍历,才能找到根结点的值。
这道题的C语言和C++还是稍微有点不一样,记下来,要简单一些。
C语言实现:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
TreeNode* Construct(int * preorder, int *inorder, int length)
{ if(preorder == NULL || inorder == NULL ) return NULL; return ConstructCore(preorder, preorder + length - 1, inorder, inorder + length - 1); } TreeNode* ConstructCore(int *startPreorder, int *endPreorder, int *startInorder, int *endInorder) { int rootvalue = startPreorder[0]; TreeNode* root = new TreeNode(); root -> val = rootvalue; root -> left = root -> right = NULL; if(startPreorder == endPreorder) { if(startPreorder == endPreorder && *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 -> left = ConstructCore(startPreorder + 1, leftPreorderEnd, startInorder, rootInorder - 1); } if(leftLength < endPreorder - startPreorder) { root -> right = ConstructCore(leftPreorderEnd + 1, endPreorder, rootInorder + 1, endInorder); } return root; } |
C++和容器实现:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) {
if(pre.size() == 0 || vin.size() == 0) return NULL; return reConstructBinaryTreeCore(pre, vin); } TreeNode* reConstructBinaryTreeCore(vector<int> pre, vector<int> vin){ if (pre.size() == 0 || vin.size() == 0){ return NULL; } //获取根节点 TreeNode* root = new TreeNode(0); root -> val = pre[0]; root -> left = root -> right = NULL; //查找根节点在中序遍历中的位置 int cur = -1; for (int i = 0; i < vin.size(); i++){ if (pre[0] == vin[i]){ cur = i; break; } } if (cur == -1){ return NULL; } //构建左子树 vector<int> leftvin; for (int i = 0; i < cur; i++){ leftvin.push_back(vin[i]); } vector<int> leftpre; for (int i = 1; i < leftvin.size() + 1; i++){ leftpre.push_back(pre[i]); } root->left = reConstructBinaryTreeCore(leftpre, leftvin); //构建右子树 vector<int> rightvin; for (int i = cur + 1; i < vin.size(); i++){ rightvin.push_back(vin[i]); } vector<int> rightpre; for (int i = 1 + leftvin.size(); i < pre.size() ; i++){ rightpre.push_back(pre[i]); } root -> right = reConstructBinaryTreeCore(rightpre, rightvin); return root; } |