题目描述
根据前序遍历和中序遍历树构造二叉树.
样例
给出中序遍历:[1,2,3]和前序遍历:[2,1,3]. 返回如下的树:
2
/ \
1 3
思路
先序遍历的第一个数为根值,在中序遍历的数组中找到该值,并则在该值左边为其左子树,右边为其右子树。
实现
/**
* @param preorder : 树的先序遍历列表
* @param inorder : 树的中序遍历列表
* @return : Root of a tree
*/
/**
使用先序遍历和中序遍历构造树的递归方法
@param preorder 树的先序遍历列表
@param inorder 树的中序遍历列表
@param preStart 树的先序遍历列表起始位置
@param preEnd 树的先序遍历列表结束位置
@param inStart 树的中序遍历列表起始位置
@param inEnd 树的中序遍历列表结束位置
@return 根节点
*/
TreeNode * buildTreeCore(vector<int> &preorder, vector<int> &inorder,int preStart, int preEnd, int inStart, int inEnd){
//构造根节点
int rootVal = preorder[preStart];
TreeNode *root = new TreeNode(rootVal);
if (preStart == preEnd) {
return root;
}
//找到在中序遍历中的根节点
int indexOfRoot = inStart;
while (rootVal != inorder[indexOfRoot] && indexOfRoot < inEnd) {
indexOfRoot++;
}
//判断是否存在左子树,若有则递归构造左子树
if (indexOfRoot > inStart) {
root -> left = buildTreeCore(preorder, inorder, preStart + 1, preStart + (indexOfRoot - inStart), inStart, indexOfRoot - 1);
}
//判断是否存在右子树,若有则递归构造右子树
if (indexOfRoot < inEnd) {
root -> right = buildTreeCore(preorder, inorder, preStart + (indexOfRoot - inStart) + 1, preEnd, indexOfRoot+1, inEnd);
}
return root;
}
/**
使用先序遍历和中序遍历构造树
@param preorder 树的先序遍历列表
@param inorder 树的中序遍历列表
@return 根节点
*/
TreeNode* buildTree(vector<int> &preorder, vector<int> &inorder) {
//参数检查
if (preorder.size() <= 0 ||
inorder.size() <= 0 ||
preorder.size() != inorder.size()) {
return NULL;
}
TreeNode *root = buildTreeCore(preorder, inorder, 0, (int)preorder.size()-1, 0, (int)inorder.size() - 1);
return root;
}