重建二叉树

重建二叉树

三月 16, 2019

题目描述



    输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。



  • 前序遍历的顺序为:根左右
  • 中序遍历的顺序为:左根右

主要思路:递归

  1. 根据前序遍历的第一个节点确定根节点
  2. 在中序遍历中找到根节点的位置
  3. 根左边的就是左子树,右边的就是右子树
  4. 构建根和左右子树
  5. 递归的进行1、2、3和4
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
if(pre.size() != vin.size())
{
cout << "length not equls" << endl;
return NULL;
}

if(pre.size() == 0)
{
cout << "pre length is 0" << endl;
return NULL;
}

int length = pre.size();
cout << "pre length is " << length << endl;

//前序遍历的第一个结点是root结点
int value = pre[0];
TreeNode *root = new TreeNode(value);
cout << "this root is " << root->val << endl;

//然后再中序遍历中找到根的位置 左边的就是左子树 右边的就是右子树
int rootIdx = 0;
for(;rootIdx < length; rootIdx ++)
{
if(vin[rootIdx] == value)
break;
}

cout << "the root at " << rootIdx << endl;

if(rootIdx >= length)
{
cout << "can't find root (value = " << value << ") in vin" << endl;
return NULL;
}

//确定左子树的长度 和 右子树的长度
int leftLength = rootIdx;
int rightLength = length - rootIdx - 1;

vector<int> preLeft(leftLength), inLeft(leftLength);
vector<int> preRight(rightLength), inRight(rightLength);

for(int i = 0; i < length; i++)
{
if(i < rootIdx)
{
//左子树
//前序遍历的第一个节点是根结点,因此是i+1
preLeft[i] = pre[i + 1];
inLeft[i] = vin[i];
cout << preLeft[i] << inLeft[i] << " ";
}else if(i > rootIdx)
{
//右子树
preRight[i - rootIdx - 1] = pre[i];
inRight[i - rootIdx - 1] = vin[i];
cout << preRight[i] << inRight[i] << " ";
}
}

cout << "left tree is" << endl;
for(int i = 0; i < leftLength; i++)
{
cout << preLeft[i] << " " << inLeft[i] << endl;

}

cout << "right tree is" << endl;
for(int i = 0; i < rightLength; i++)
{
cout << preRight[i] << " " << inRight[i] << endl;

}

root->left = reConstructBinaryTree(preLeft, inLeft);
root->right = reConstructBinaryTree(preRight, inRight);

return root;


}
};