A full binary tree is a tree in which every node has either 0 or 2 children. Write an efficient algorithm to construct a full binary tree from a given preorder and postorder sequence.

For example,

Input:
 
Preorder traversal : { 1, 2, 4, 5, 3, 6, 8, 9, 7 }
Postorder traversal: { 4, 5, 2, 8, 9, 6, 7, 3, 1 }
 
 
Output: Following full binary tree

Full Binary Tree

Practice this problem

We can construct a unique binary tree from inorder and preorder sequences and the inorder and postorder sequences. But preorder and postorder sequences don’t provide enough information to create a unique binary tree. Several binary trees can be constructed due to ambiguity.

For example, consider the following skewed trees:

        a         a
       /           \
      b             b
     /               \
    c                 c
   /                   \
  d                     d

For both above trees, the preorder and postorder traversal result in the same sequence of numbers:

preorder  : { a, b, c, d }
postorder : { d, c, b, a }

Therefore, it is impossible to construct a unique binary tree with preorder and postorder sequences. However, a unique full binary tree can easily be constructed with them. To illustrate, consider the following preorder and postorder sequence:

preorder  : { 1, 2, 4, 5, 3, 6, 8, 9, 7 }
postorder : { 4, 5, 2, 8, 9, 6, 7, 3, 1 }

We know that the root is the first element in the preorder sequence and the last element in the postorder sequence. Therefore, the root node is 1. Then locate the next element in the preorder sequence, which must be the left child of the root node. In this case, the left child is 2. Now since 2 is the root node of the left subtree, all nodes before 2 in the postorder sequence must be present in the left subtree of the root node, i.e., {4, 5, 2} and all the nodes after 2 (except the last) must be present in the right subtree, i.e., {8, 9, 6, 7, 3}. Now the problem is reduced to building the left and right subtrees and linking them to the root node.

Left subtree:
 
Postorder : {4, 5, 2}
Preorder  : {2, 4, 5}
 
Right subtree:
 
Postorder : {8, 9, 6, 7, 3}
Preorder  : {3, 6, 8, 9, 7}

The idea is to recursively follow the above approach until the complete tree is constructed. This is demonstrated below in C++, Java, and Python:

C++


Download  Run Code

Output:

Inorder traversal is 4 2 5 1 8 6 9 3 7

Java


Download  Run Code

Output:

Inorder traversal is 4 2 5 1 8 6 9 3 7

Python


Download  Run Code

Output:

Inorder traversal is 4 2 5 1 8 6 9 3 7

Note that the above algorithm will ensure a unique binary tree only when all keys in the given preorder/postorder sequence are distinct. For example, two full binary trees exist for following preorder and postorder sequences whose node keys are not distinct:

The preorder traversal is { 0, 1, 1, 1, 1 }
The postorder traversal is { 1, 1, 1, 1, 0 }
 
      0
     / \
    1   1
   / \
  1   1
  
  
    0
   / \
  1   1
     / \
    1   1

The time complexity of the above solution is O(n) and requires O(n) extra space, where n is the total number of nodes in the binary tree.