Question:
通过二叉树的中序遍历序列、后序遍历序列构造二叉树。
Ideas:
中序遍历(左根右),后序遍历(左右根),根据后序遍历序列可以得到根,在中序遍历中找到根的位置,将inorder分为左右子树,针对左右子树的中序、后序序列再开始构建。采用递归。
递归的关键是结束条件分析:每次递归时都要携带inorder的开始和结束的位置,postorder的开始和结束位置,当开始和结束位置相等时说明就只有一个节点,即可结束递归。
public TreeNode buildTree(int[] inorder, int[] postorder) {
if(inorder.length!=postorder.length||inorder.length==0||postorder.length==0){
return null;
}
return constructTreeNode(inorder,0,inorder.length-1,postorder,0,postorder.length-1);
}
public TreeNode constructTreeNode(int[] inorder,int inBegin,int inEnd,
int[] postorder,int postBegin,int postEnd){
int val = postorder[postEnd];
TreeNode rootNode = new TreeNode(val);
rootNode.left = rootNode.right = null;
//中序遍历中有一个节点
if(inBegin==inEnd){
//再判断后序遍历中也只有一个节点,且中序和后序中两个节点相等,则返回
if(postBegin==postEnd&&inorder[inEnd]==postorder[postEnd]){
return rootNode;
}//其他的情况就报错。说明输入序列非法
}
int rootIndex = inBegin;
//先在中序遍历中找到根节点,分成左右子树
while(inorder[rootIndex]!=val&&rootIndex<=inEnd){
rootIndex++;
}
//中序分为左右两子树
int leftLength = rootIndex-inBegin;
int inLeftEnd = rootIndex-1;
int inRightBegin = rootIndex+1;
int postLeftEnd = postBegin+leftLength-1;
int postRightBegin = postLeftEnd+1;
int rightLength = inEnd-rootIndex;
if(leftLength>0){
rootNode.left = constructTreeNode(inorder,inBegin,inLeftEnd,postorder,postBegin,postLeftEnd);
}
if(rightLength>0){
rootNode.right = constructTreeNode(inorder,inRightBegin,inEnd,postorder,postRightBegin,postEnd-1);
}
return rootNode;
}