Print K inorder successors of a Binary Tree in O(1) space

Given a Binary Tree and two numbers P and K, the task is to print the K Inorder Successor of the given number P from the Binary tree in constant space.
Examples: 
 

Input: Tree: 
 

          1
        /   \
      12      11
     /       /   \
    3       4     13
            \      /
            15    9

P = 12, K = 4 
Output: 1 4 15 11 
Explanation: 
Inorder traversal: 3 12 1 4 15 11 9 13 
The 4 Inorder Successor of a node 12 are {1, 4, 15, 11}
Input: Tree: 
 

                  5
                /   \
              21    77
             /  \      \
            61   16    36
                  \     /
                   10  3
                  /
                 23

P = 23, K = 3 
Output: 10 5 77 
Explanation: 
Inorder traversal: 61 21 16 23 10 5 77 3 36 
The 3 Inorder Successor Of a node 23 are {10, 5, 77}. 
 

 



Approach: 
In order to solve this problem, we are using the Morris Inorder Traversal of a Binary Tree to avoid the use of any extra space. Search for the node ‘P’ while generating the inorder sequence. Once found, print the next K nodes that appear in the inorder sequence.
Below is the implementation of the above approach:
 

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation to print K Inorder
// Successor of the Binary Tree
// without using extra space
 
#include <bits/stdc++.h>
using namespace std;
 
/* A binary tree Node has data,
  a pointer to left child
  and a pointer to right child */
struct tNode {
    int data;
    struct tNode* left;
    struct tNode* right;
};
 
/* Function to traverse the
  binary tree without recursion and
  without stack */
void MorrisTraversal(struct tNode* root,
                     int p, int k)
{
    struct tNode *current, *pre;
 
    if (root == NULL)
        return;
 
    bool flag = false;
 
    current = root;
 
    while (current != NULL) {
 
        // Check if the left child exists
        if (current->left == NULL) {
 
            if (flag == true) {
                cout << current->data
                     << " ";
                k--;
            }
            if (current->data == p)
                flag = true;
 
            // Check if K is 0
            if (k == 0)
                flag = false;
 
            // Move current to its right
            current = current->right;
        }
        else {
 
            // Find the inorder predecessor
            // of current
            pre = current->left;
            while (pre->right != NULL
                   && pre->right != current)
                pre = pre->right;
 
            /* Make current as the right
               child of its inorder
                  predecessor */
            if (pre->right == NULL) {
                pre->right = current;
                current = current->left;
            }
 
            /* Revert the changes made in the
               'if' part to restore the original
               tree i.e., fix the right child
                 of predecessor */
            else {
                pre->right = NULL;
                if (flag == true) {
                    cout << current->data
                         << " ";
                    k--;
                }
                if (current->data == p)
                    flag = true;
 
                if (k == 0)
                    flag = false;
 
                current = current->right;
            }
        }
    }
}
 
/* Function that allocates
   a new Node with the
   given data and NULL left
   and right pointers. */
struct tNode* newtNode(int data)
{
    struct tNode* node = new tNode;
    node->data = data;
    node->left = NULL;
    node->right = NULL;
 
    return (node);
}
 
/* Driver code*/
int main()
{
 
    struct tNode* root = newtNode(1);
 
    root->left = newtNode(12);
    root->right = newtNode(11);
    root->left->left = newtNode(3);
    root->right->left = newtNode(4);
    root->right->right = newtNode(13);
 
    root->right->left->right = newtNode(15);
    root->right->right->left = newtNode(9);
 
    int p = 12;
    int k = 4;
 
    MorrisTraversal(root, p, k);
 
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation to print K Inorder
// Successor of the Binary Tree
// without using extra space
 
// A binary tree tNode has data,
// a pointer to left child
// and a pointer to right child
class tNode
{
    int data;
    tNode left, right;
 
    tNode(int item)
    {
        data = item;
        left = right = null;
    }
}
 
class BinaryTree{
     
tNode root;
 
// Function to traverse a binary tree
// without recursion and without stack
void MorrisTraversal(tNode root, int p, int k)
{
    tNode current, pre;
 
    if (root == null)
        return;
         
    boolean flag = false;
    current = root;
     
    while (current != null)
    {
        if (current.left == null)
        {
            if (flag == true)
            {
                System.out.print(current.data + " ");
                k--;
            }
            if (current.data == p)
            {
                flag = true;
            }
            if (k == 0)
            {
                flag = false;
            }
            current = current.right;
        }
        else
        {
             
            // Find the inorder predecessor
            // of current
            pre = current.left;
            while (pre.right != null &&
                   pre.right != current)
                pre = pre.right;
 
            // Make current as right child of
            // its inorder predecessor
            if (pre.right == null)
            {
                pre.right = current;
                current = current.left;
            }
 
            // Revert the changes made in the
            // 'if' part to restore the original
            // tree i.e., fix the right child of
            // predecessor
            else
            {
                pre.right = null;
                if (flag == true)
                {
                    System.out.print(current.data + " ");
                    k--;
                }
                if (current.data == p)
                {
                    flag = true;
                }
                if (k == 0)
                {
                    flag = false;
                }
                current = current.right;
            }
        }
    }
}
 
// Driver code
public static void main(String args[])
{
    BinaryTree tree = new BinaryTree();
     
    tree.root = new tNode(1);
    tree.root.left = new tNode(12);
    tree.root.right = new tNode(11);
    tree.root.left.left = new tNode(3);
    tree.root.right.left = new tNode(4);
    tree.root.right.right = new tNode(13);
     
    tree.root.right.left.right = new tNode(15);
    tree.root.right.right.left = new tNode(9);
     
    int p = 12;
    int k = 4;
     
    tree.MorrisTraversal(tree.root, p, k);
}
}
 
// This code is contributed by MOHAMMAD MUDASSIR
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation to print K Inorder
# Successor of the Binary Tree
# without using extra space
  
''' A binary tree Node has data,
  a pointer to left child
  and a pointer to right child '''
class tNode:
     
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
  
''' Function to traverse the
  binary tree without recursion and
  without stack '''
def MorrisTraversal(root, p, k):
 
    current = None
    pre = None
  
    if (root == None):
        return;
  
    flag = False;
  
    current = root;
  
    while (current != None):
  
        # Check if the left child exists
        if (current.left == None):
  
            if (flag == True):
                print(current.data, end = ' ')
                 
                k -= 1
             
            if (current.data == p):
                flag = True;
  
            # Check if K is 0
            if (k == 0):
                flag = False;
  
            # Move current to its right
            current = current.right;
         
        else:
  
            # Find the inorder predecessor
            # of current
            pre = current.left
             
            while (pre.right != None and pre.right != current):
                pre = pre.right;
  
            # Make current as the right
            #child of its inorder predecessor
            if(pre.right == None):
                pre.right = current;
                current = current.left;
                 
            # Revert the changes made in the
            # 'if' part to restore the original
            # tree i.e., fix the right child
            # of predecessor
            else:
                pre.right = None;
                if (flag == True):
                    print(current.data, end = ' ')
                     
                    k -= 1
                 
                if (current.data == p):
                    flag = True;
  
                if (k == 0):
                    flag = False;
  
                current = current.right;
  
''' Function that allocates
   a new Node with the
   given data and None left
   and right pointers. '''
def newtNode(data):
 
    node = tNode(data);
    return (node);
 
# Driver code
if __name__=='__main__':
  
    root = newtNode(1);
  
    root.left = newtNode(12);
    root.right = newtNode(11);
    root.left.left = newtNode(3);
    root.right.left = newtNode(4);
    root.right.right = newtNode(13);
  
    root.right.left.right = newtNode(15);
    root.right.right.left = newtNode(9);
  
    p = 12;
    k = 4;
  
    MorrisTraversal(root, p, k);
  
# This code is contributed by rutvik_56
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to print inorder traversal
// without recursion and stack
using System;
 
// A binary tree tNode has data,
// pointer to left child and a
// pointer to right child
class BinaryTree{
     
tNode root;
 
public class tNode
{
    public int data;
    public tNode left, right;
 
    public tNode(int item)
    {
        data = item;
        left = right = null;
    }
}
 
// Function to traverse binary tree without
// recursion and without stack
void MorrisTraversal(tNode root, int p, int k)
{
    tNode current, pre;
 
    if (root == null)
        return;
 
    current = root;
    bool flag = false;
    while (current != null)
    {
        if (current.left == null)
        {
            if (flag == true)
            {
                Console.Write(current.data + " ");
                k--;
            }
            if (current.data == p)
            {
                flag = true;
            }
            if (k == 0)
            {
                flag = false;
            }
            current = current.right;
        }
        else
        {
             
            // Find the inorder predecessor
            // of current
            pre = current.left;
            while (pre.right != null &&
                   pre.right != current)
                pre = pre.right;
 
            // Make current as right child
            // of its inorder predecessor
            if (pre.right == null)
            {
                pre.right = current;
                current = current.left;
            }
 
            // Revert the changes made in
            // if part to restore the original
            // tree i.e., fix the right child
            // of predecssor
            else
            {
                pre.right = null;
                if (flag == true)
                {
                    Console.Write(current.data + " ");
                    k--;
                }
                if (current.data == p)
                {
                    flag = true;
                }
                if (k == 0)
                {
                    flag = false;
                }
                current = current.right;
            }
        }
    }
}
 
// Driver code
public static void Main(String []args)
{
    BinaryTree tree = new BinaryTree();
 
    tree.root = new tNode(1);
    tree.root.left = new tNode(12);
    tree.root.right = new tNode(11);
    tree.root.left.left = new tNode(3);
    tree.root.right.left = new tNode(4);
    tree.root.right.right = new tNode(13);
     
    tree.root.right.left.right = new tNode(15);
    tree.root.right.right.left = new tNode(9);
     
    int p = 12;
    int k = 4;
     
    tree.MorrisTraversal(tree.root, p, k);
}
}
 
// This code is contributed by MOHAMMAD MUDASSIR
chevron_right

Output: 
1 4 15 11

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.





Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : MohammadMudassir, rutvik_56

Article Tags :
Practice Tags :