Construct Binary Tree from Inorder and Postorder Traversal

Given inorder and postorder traversal of a tree, construct the binary tree.

Analysis

This problem can be illustrated by using a simple example.

in-order:   4 2 5  (1)  6 7 3 8
post-order: 4 5 2  6 7 8 3  (1)

From the post-order array, we know that last element is the root. We can find the root in in-order array. Then we can identify the left and right sub-trees of the root from in-order array.

Using the length of left sub-tree, we can identify left and right sub-trees in post-order array. Recursively, we can build up the tree.

For this example, the constructed tree is:
construct-binary-tree-from-inorder-and-postorder-traversal

Java Solution

public TreeNode buildTree(int[] inorder, int[] postorder) {
	int inStart = 0;
	int inEnd = inorder.length - 1;
	int postStart = 0;
	int postEnd = postorder.length - 1;
 
	return buildTree(inorder, inStart, inEnd, postorder, postStart, postEnd);
}
 
public TreeNode buildTree(int[] inorder, int inStart, int inEnd,
		int[] postorder, int postStart, int postEnd) {
	if (inStart > inEnd || postStart > postEnd)
		return null;
 
	int rootValue = postorder[postEnd];
	TreeNode root = new TreeNode(rootValue);
 
	int k = 0;
	for (int i = 0; i < inorder.length; i++) {
		if (inorder[i] == rootValue) {
			k = i;
			break;
		}
	}
 
	root.left = buildTree(inorder, inStart, k - 1, postorder, postStart,
			postStart + k - (inStart + 1));
	// Becuase k is not the length, it it need to -(inStart+1) to get the length
	root.right = buildTree(inorder, k + 1, inEnd, postorder, postStart + k- inStart, postEnd - 1);
	// postStart+k-inStart = postStart+k-(inStart+1) +1
 
	return root;
}

12 thoughts on “Construct Binary Tree from Inorder and Postorder Traversal”

  1. why are we using two functions with varying parameters,what would be the output if only first function is used.

  2. int k = 0;
    for (int i = 0; i < inorder.length; i++) {
    if (inorder[i] == rootValue) {
    k = i;
    break;
    }
    }

    i should be = to instart and not 0.

  3. A solution for the case where duplicated values are admitted.
    Note: I used sub list for clarity may/should be changed to indexed “sublists” for efficiency.


    TreeNode reconstruct(List inOrder, List postOrder) {
    int rootValue = postOrder.get(postOrder.size() - 1);
    TreeNode root = new TreeNode(rootValue);
    for (int i = 0; i 0) {
    TreeNode left =
    reconstruct(inOrder.subList(0, i), postOrder.subList(0, postOrder.size() - rightSize - 1));
    if (left == null) continue; //wasn't the root what we found
    root.left = left;
    }
    if (rightSize > 0) {
    TreeNode right =
    reconstruct(
    inOrder.subList(i + 1, inOrder.size()),
    postOrder.subList(postOrder.size() - rightSize - 1, postOrder.size() - 1));
    if (right == null) continue; //wasn't the root what we found
    root.right = right;
    }
    return root; //both subtrees succeeded
    }
    }
    return null;
    }

  4. This code is working only if all elements are unique, But I tried this method on the following:

    int[] inorder = {4,1,5,1,6,7,3,8};
    int[] postorder = {4,5,1,6,7,8,3,1};

    I got this error Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: -1

  5. Arrays.asList does not work as expected for primitives, only Objects. that change would give you the wrong answer

  6. Nice.
    Just some suggestions for more readable code:

    1. use inclusive start index and exclusive end index. [start, end) so that you don’t need hairy +1 and -1.
    2.give these expressions a name: postStart+k-(inStart+1); postStart+k-inStart.

  7. int k=0;

    for(int i=0; i< inorder.length; i++){
    if(inorder[i]==rootValue){
    k = i;
    break;
    }

    }

    can be simplified as

    int k = java.util.Arrays.asList(inorder).indexOf(rootValue)

  8. in-order: 4 2 5 (1) 6 7 3 8

    is this correct inorder as left subtree element of 1 are greater than 1. Left Subtree should be lesser

  9. The for loop “for(int i=0; i< inorder.length; i++){" can be simplified to "for(int i = inStart; i <= inEnd; ++i){" in case duplicated

Leave a Comment