知识:二叉树
二叉树遍历:每个节点的分支都遵循对应的访问顺序,体现“递归调用”
前序遍历:根→左→右
性质:
中序遍历:左→根→右
性质:中序节点的索引i,i-1是左子树的末端索引,i+1是右子树的起始索引。
后序遍历:左→右→根
问题:根据某二叉树的前序遍历和中序遍历的结果,重建出该二叉树。(假设输入的前序遍历和中序遍历的结果中都不含重复的数字。)
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
TreeNode root=reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
return root;
}
//前序遍历{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}
private TreeNode reConstructBinaryTree(int [] pre,int startPre,int endPre,int [] in,int startIn,int endIn) {
if(startPre>endPre||startIn>endIn)
return null;
TreeNode root=new TreeNode(pre[startPre]);//一开始,根节点是数组的第一个
for(int i=startIn;i<=endIn;i++)
if(in[i]==pre[startPre]){//找到二叉树根节点
root.left=reConstructBinaryTree(pre,startPre+1,startPre+i-startIn,in,startIn,i-1);//左子树根节点.i是中序根节点的索引,
//i-startIn是左子树的大小(中序:左、根、右,所以数组中根节点索引-1就是左子树大小)
//而startPre+它,就是前序中左子树结束节点在前序数组中的索引,
//这样就相当于查找前序的左子树。
//而i-1是中序的左子树末端节点索引,
//以此递归。直到startPre+1>startPre+i-startIn
//或者startIn>i-1,代表没有节点了。
//总结就是中序计算出左子树大小,前序提供根节点在前序数组中的索引,这样在前序中框出来左子树
//i-1是中序的左子树末端节点索引,中序的左子树起始节点索引就是起始索引
root.right=reConstructBinaryTree(pre,i-startIn+startPre+1,endPre,in,i+1,endIn);//类似的方法框出来右子树。
//(i-startIn(左子树的大小)+startPre)(前序最左的节点的索引)+1,就是右子树根节点索引。i+1是右子树的起始节点索引
break;
}
return root;
}
}