Last Updated: 22 Oct, 2020

Inorder Sucessor

Moderate
Asked in companies
InnovaccerAmazonIntuit

Problem statement

You have been given an arbitrary binary tree and a node of this tree. You need to find the inorder successor of this node in the tree.

The inorder successor of a node in a binary tree is that node that will be visited immediately after the given node in the inorder traversal of the tree. If the given node is visited last in the inorder traversal, then its inorder successor is NULL.

The inorder traversal of a binary tree is the traversal method in which for any node its left subtree is visited first, then the node itself, and then the right subtree.

Note
1. Each node is associated with a unique integer value. 

2. The node for which the successor is to be found is guaranteed to be part of the tree.
Input Format:
The first line contains a single integer 'T' representing the number of test cases. 

The first line of each test case will contain the values of the nodes of the tree in the level order form ( -1 for NULL node) Refer to the example for further clarification.

The second and the last line of each test case will contain the value of the node for which the inorder successor is to be found.

Example: 
Consider the binary tree:

altImage

The input of the tree depicted in the image above will be like: 
 1
 2 3
 4 -1 5 6
-1 7 -1 -1 -1 -1
-1 -1

Explanation :
Level 1 :
The root node of the tree is 1

Level 2 :
Left child of 1 = 2
Right child of 1 = 3

Level 3 :
Left child of 2 = 4
Right child of 2 = null (-1)
Left child of 3 = 5
Right child of 3 = 6

Level 4 :
Left child of 4 = null (-1)
Right child of 4 = 7
Left child of 5 = null (-1)
Right child of 5 = null (-1)
Left child of 6 = null (-1)
Right child of 6 = null (-1)

Level 5 :
Left child of 7 = null (-1)
Right child of 7 = null (-1)

The first not-null node (of the previous level) is treated as the parent of the first two nodes of the current level. The second not-null node (of the previous level) is treated as the parent node for the next two nodes of the current level and so on.

The input ends when all nodes at the last level are null (-1).
Output Format:
For each test case, print a single line that contains the value of the successor node, or NULL if it does not have an inorder successor.

The output of each test case will be printed in a separate line.
Note:
You do not need to print anything, it has already been taken care of. Just implement the given function. 
Constraints:
1 <= 'T' <= 100
2 <= 'N' <= 10 ^ 3  
1 <=  'NODEVALUE' <= 10 ^ 9

Where 'N' is the number of nodes and 'NODEVALUE' is the value of the node.

Time Limit: 1sec.

Approaches

01 Approach

  • The fact that all the data values are unique makes the solution look very intuitive.
  • We can simply store the inorder traversal of the given tree in some data structure, most probably arrays, and find the element present after the given node in the array.
  • For inorder traversal, we can write a simple recursion code, where for every node, its left subtree is visited recursively, and then the node is visited(its value stored in the array), and then its right subtree.
  • After the traversal, we can find the required data value in the array, and if that value is not present at the end of the array, our answer will be the next element, or NULL otherwise.

02 Approach

  • This problem can be solved without actually storing the whole inorder traversal of the tree if we can observe some properties of the inorder traversal of a binary tree.
    As we know, in the inorder traversal the right subtree of a node is visited after the node, thus if the right subtree of a node is not 'NULL', then its inorder successor must lie in its right subtree.
    The above observation broadly divides the problem into two cases:
  • The right subtree of the node is not 'NULL'.
    The right subtree of the node is 'NULL'.
  • For the first case, notice that if the right subtree is not 'NULL', then after the node, the first node that will be visited in the right subtree will be the leftmost node in the right subtree. This is because in the right subtree also the order of traversal will be {left, root, right}.
  • We will recursively visit the left node of this subtree until its left 'CHILD' is 'NULL'. This node will be the answer.
  • The second case is a bit tricky as we don't have a right subtree for the given node.
  • Notice that in the inorder traversal of a tree, the 'PARENT' node is visited after its left subtree, but before its right subtree. So any node belonging to the left subtree of a node will be visited before that node.
    Thus if the node for which inorder successor is to be found doesn’t have a right subtree, we need to find a {'PARENT' -> 'CHILD'} relation such that the 'CHILD' is the root of the left subtree of the 'PARENT', and the given node belongs to the 'CHILD'. This is because according to the 1st point, after this node the 'PARENT' would be the next visited node.
    So, we can run an inorder traversal, where we first search for the node for which the successor is to be found. We first search for the node in the left subtree of the current node. If we find it in the left subtree, we store that node in some answer variable and return.
    If we do not find the node in the left subtree, we look for the node in the right subtree, and if we find it we backtrack returning the current node as long as we don’t find the relation mentioned in the 2nd point.

03 Approach

  • According to the definition of the inorder successor, it is the node which is visited immediately after the given node. Thus if we somehow visit the successor node before the given node, we will find our successor easily as when we visit the given node, we will know the node we have visited before it.
  • So what we will be doing is something similar to reverse inorder traversal of the given binary tree.
  • The inorder traversal follows this order:{left, root, right}, so the reverse inorder traversal will follow: {right, root, left}. If we follow the reverse inorder, clearly we will visit the inorder successor first, then the actual node.
  • So we will store the parent node as the root node in each recursive call, and when we visit the actual node, we know the inorder successor is nothing but the parent node itself.