一,题目描述及分析
1.题目: 根据一棵树的前序遍历与中序遍历构造二叉树。
注意:你可以假设树中没有重复的元素
2.示例:
例如给出:
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下二叉树:
3.分析
1)先序遍历的第一个节点一定是树根节点,接下来就是左右子树的根节点
2)中序遍历左子树一定在根节点左侧,右子树一定在根节点右侧
4,思路
1)先在先序遍历结果中取到根节点,
2)再拿着这个根节点去中序遍历结果中判断,很容易就看到了其对应的左右子树中序遍历的结果
例如:在先序遍历数组取到树的根节点3,再去中序遍历数组中查看,很容易看出根节点3对应的左子树中序遍历结果为9,右子树的中序遍历结果为15 20 7
二,代码实现
1,实现思想:
1)借助一个辅助方法递归先序遍历,访问节点操作“构造节点”,同时需要给这个辅助方法加上一队下标参数,通过这对下标指定当前节点对应得中序遍历结果是啥
2)根据中序遍历结果与当前节点在中序遍历结果中得位置划分出左右子树,再进一步去递归处理左右子树即可
2,上代码:
private int index ; //用来表示当前访问到先序遍历的第几个元素le
public TreeNode buildTree(int[] preorder,int[] inorder){
index = 0;
return buildTreeHepler(preorder,inorder,0,inorder.length);
}
//[left,right)这个区间就表示当前preorder[index]对应的节点的中序遍历结果
private TreeNode buildTreeHepler(int[] preorder, int[] inorder, int left, int right) {
if(left >= right){
return null; //中序遍历结果为空,这个树就是空树
}
if(index >= preorder.length ){
//遍历元素结束
return null;
}
//根据当前根节点值创建新节点
TreeNode root= new TreeNode(preorder[index]);
index++;//节点创建完毕index++准备处理下一个节点
//根据该节点在中序遍历结果中的位置把inorder数组划分成两部分
int post = find(inorder,left,right,root.val);
//[left,post)表示当前root左子树的中序遍历结果
//[pos+1,right)表示当前root右子树的中序遍历结果
root.left = buildTreeHepler(preorder,inorder,left,post);
root.right = buildTreeHepler(preorder, inorder, post+1, right);
return root;
}
private int find(int[] inorder,int left,int right,int toFind){
for (int i = left; i < right ; i++) {
if(inorder[i] == toFind){
return i;
}
}
return -1;
}