从中序与后序遍历序列构造二叉树
根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
思路+代码+注释:
public class OneZeroSix {
TreeNode root=null;
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public TreeNode buildTree(int[] inorder, int[] postorder) {
/*
思路:通过后序遍历确定根节点,然后根据中序遍历确定中序遍历左子树节点以及右子树节点,有了左子树节点个数后就可以确定后序遍历左子树序列和右子树序列,进行递归求解
*/
List<Integer> inorders=new ArrayList<>();
List<Integer> postorders=new ArrayList<>();
for (int i:inorder
) {
inorders.add(i);
}
for (int i:postorder
) {
postorders.add(i);
}
buildTree(inorders,postorders,null,false,false);
return root;
}
public void buildTree(List<Integer> inorder, List<Integer> postorder,TreeNode rootNode,boolean left,boolean right) {
if (inorder.size()==0)
{
return;
}
int val=postorder.get(postorder.size()-1);
TreeNode node=new TreeNode(val);
if (rootNode!=null)
{
if (left)
{
rootNode.left=node;
}else if (right)
{
rootNode.right=node;
}
}else {
root=node;
}
List<Integer> leftInorder=new ArrayList<>();
List<Integer> rightInorder=new ArrayList<>();
int rootIndex=0;
int leftNum=0;
for (int i = 0; i < inorder.size(); i++) {
int num=inorder.get(i);
if (num!=val)
{
leftNum++;
leftInorder.add(num);
}else {
rootIndex=i;
break;
}
}
for (int i = rootIndex+1; i < inorder.size(); i++) {
rightInorder.add(inorder.get(i));
}
List<Integer> leftPostorder=new ArrayList<>();
List<Integer> rightPostorder=new ArrayList<>();
int leftPostNum=0;
for (int i = 0; i < postorder.size()-1; i++) {
leftPostNum++;
if (leftPostNum<=leftNum)
{
leftPostorder.add(postorder.get(i));
}else {
rightPostorder.add(postorder.get(i));
}
}
buildTree(leftInorder,leftPostorder,node,true,false);
buildTree(rightInorder,rightPostorder,node,false,true);
}
}