剑指offer编程-重建二叉树
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路:
1.根据前序第一个为根节点;
2.然后在中序序列中找到根节点,根节点左侧为它的左子树,根节点右侧为它的右子树;
3.递归对左子树重复步骤1,步骤2。注意递归终止条件:只有一个节点。
#include<iostream> #include<vector> //#include <cstdlib> using namespace std; struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; class Solution { public: TreeNode* reConstructCore(int *pre_start, int *pre_end, int *vin_start, int *vin_end){ int root_value = *pre_start; TreeNode* root = new TreeNode(root_value); root->val = root_value; root->left = nullptr; root->right = nullptr; if (pre_start == pre_end){ if (vin_start == vin_end) return root; else throw std::exception("Invalid Input"); } else{ int leftnum = 0; while (*(vin_start + leftnum) != root_value) leftnum++; if (leftnum > 0) root->left = reConstructCore(pre_start + 1, pre_start + leftnum , vin_start, vin_start + leftnum - 1); if (vin_end-vin_start>leftnum) root->right = reConstructCore(pre_start + leftnum + 1, pre_end, vin_start + leftnum + 1, vin_end); } return root; } TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) { int *pre_start = &pre[0]; int *pre_end = &pre[pre.size()-1]; int *vin_start = &vin[0]; int *vin_end = &vin[vin.size() - 1]; return reConstructCore(pre_start, pre_end, vin_start, vin_end); } }; int _tmain(int argc, _TCHAR* argv[]) { int a[] = { 1, 2, 4, 7, 3, 5, 6, 8, 4,7,2,1,5,3,8,6}; vector<int> pre(a, a + 8); vector<int> vin(a+8, a + 16); Solution S; TreeNode *root; root = S.reConstructBinaryTree(pre, vin); cout << "按任意键继续……"; cin.clear(); cin.sync(); cin.get(); return 0; }
测试用例:
1.普通二叉树(完全二叉树,不完全二叉树)。
2.特殊二叉树(只有左子树,只有右子树,只有一个节点的二叉树)。
3.特殊输入(空指针,前序遍历和中序遍历不匹配)。
编程,vector:
赋值方式;
指向vector数组的指针:即定义一个整形指针指向vector数组第一个元素的位置。不能指向vector数组名。