package Tree;
public class PreAndIn_ToCreateTree {
//根据前序与中序遍历构造二叉树
//1.前序的第一个元素就是根节点
//2.中序中,根节点左侧就是左子树的中序,根节点的右侧就是右子树的中序
//3.前序中,知道了哪些节点是左子树,哪些节点是右子树之后,此时,
// 前序中对应的序列,也就是左右子树前序的结果
//例:
//前序结果:3,9,20,15,7
//中序结果:9,3,15,20,7
//1.根:3
//2.拿着3去中序中查找,9是左子树,15,20,7是右子树
//3.回到前序,20,15,7就是刚才3的右子树的前序结果,此时20就是根节点
//4.拿着20去对应在中序结果15,20,7中进行查找,15是左子树,7是右子树
//通过index表示当前取到了preorder中的哪个元素
private int index = 0;
public TreeNode PreAndInToCreateTree(int[] preorder,int[] inorder){
//index归零
index = 0;
//辅助函数
return buildTreeHelper(preorder,inorder,0,preorder.length);
}
//约定[inLeft,inRight)前闭后开区间
public TreeNode buildTreeHelper(int[] preorder,int[] inorder,int inLeft,int inRight){
//in为空区间
if(inLeft>=inRight){
return null;
}
//index已经遍历完
if(index>=preorder.length){
return null;
}
//取出index对应的元素,构造当前根节点
TreeNode root = new TreeNode(preorder[index]);
//取下一个元素
index++;
//接下来找到刚才root在中序中的位置
int pos = findPos(preorder,inLeft,inRight,root.val);
//先递归左子树,后递归右子树
//因为前序是根->左->右
root.left = buildTreeHelper(preorder,inorder,inLeft,pos);
root.right = buildTreeHelper(preorder,inorder,pos+1,inRight);
return root;
}
public int findPos(int[] inorder,int inLeft,int inRight,int val){
//循环遍历即可
for(int i = inLeft;i<inRight;i++){
if(inorder[i]==val){
return i;
}
}
//越界判断
return -1;
}
}
最后提一嘴,
如果是后序和中序构造二叉树,可以将后序遍历结果逆置,即从左右根变为根右左,是前序的镜像,此时只要更换递归左右子树的前后顺序即可

被折叠的 条评论
为什么被折叠?



