二叉树是数据结构中比较重要的一部分,通过给定的二叉树可以进行前序中序和后序遍历,但是反过来,如果给定前序遍历和中序遍历,是否可以重建出一棵二叉树。答案是,可以。
/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ //使用vector容器作为参数 class Solution { public: TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) { //判断给定的前序以及中序是否为空 if(pre.size()==0||vin.size()==0) return NULL; int* preStart = &pre[0]; //取前序的第一个元素地址,定义一个指针指向 int* preEnd = &pre[pre.size()-1];//取前序的最后一个元素地址,定义一个指针指向 int* vinStart = &vin[0];//取中序的第一个元素地址,定义一个指针指向 int* vinEnd = &vin[vin.size()-1];//取中序最后一个元素地址,定义一个指针指向 return ConstructTree(preStart,preEnd,vinStart,vinEnd); } TreeNode* ConstructTree(int* preStart,int* preEnd,int* vinStart,int* vinEnd) { int data = preStart[0];//取出前序的第一个数据 TreeNode* root = new TreeNode(data);//以该数据作为该重建树的根节点,因为由前序遍历的特点可知,第一个数据就是根节点 if(preStart==preEnd) { if(preStart == vinEnd&& preEnd==vinStart) return root; } int* rootInorder = vinStart;//定义一个指针,开始遍历中序数组,直到找到根节点再停止,这样就可以分出左子树和右子树 while(rootInorder<=vinEnd && *rootInorder!=data) ++rootInorder; if(rootInorder==vinEnd && *rootInorder!=root->val) return NULL; //如果在中序中没有找到根节点则返回空 int leftlength = rootInorder-vinStart; int* leftpreOrderEnd = preStart+leftlength;//根据在中序中找到的左子树就可以找出前序中的左子树 //再依次根据递归即可重建该二叉树 if(leftlength>0) { root->left = ConstructTree(preStart+1,leftpreOrderEnd,vinStart,rootInorder-1); } if(leftlength<preEnd-preStart) { root->right = ConstructTree(leftpreOrderEnd+1,preEnd,rootInorder+1,vinEnd); } return root; } };