Open In App

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

Last Updated : 05 Jan, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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:
 

C++




// 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;
}


Java




// Java 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
{
    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


Python3




# 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


C#




// C# program to print inorder traversal
// without recursion and stack
using System;
 
// A binary tree Node 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 predecessor
            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


Javascript




<script>
    // Javascript 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
    {
        constructor(item) {
           this.left = null;
           this.right = null;
           this.data = item;
        }
    }
     
    let root;
  
    // Function to traverse a binary tree
    // without recursion and without stack
    function MorrisTraversal(root, p, k)
    {
        let current, pre;
 
        if (root == null)
            return;
 
        let flag = false;
        current = root;
 
        while (current != null)
        {
            if (current.left == null)
            {
                if (flag == true)
                {
                    document.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 the
                // 'if' part to restore the original
                // tree i.e., fix the right child of
                // predecessor
                else
                {
                    pre.right = null;
                    if (flag == true)
                    {
                        document.write(current.data + " ");
                        k--;
                    }
                    if (current.data == p)
                    {
                        flag = true;
                    }
                    if (k == 0)
                    {
                        flag = false;
                    }
                    current = current.right;
                }
            }
        }
    }
     
    root = new tNode(1);
    root.left = new tNode(12);
    root.right = new tNode(11);
    root.left.left = new tNode(3);
    root.right.left = new tNode(4);
    root.right.right = new tNode(13);
      
    root.right.left.right = new tNode(15);
    root.right.right.left = new tNode(9);
      
    let p = 12;
    let k = 4;
      
    MorrisTraversal(root, p, k);
 
// This code is contributed by decode2207.
</script>


 
 

Output: 

1 4 15 11

 

Time Complexity: The time complexity of the above code is O(n), as it traverses the whole tree once to print the k inorder successors of the given node. The time complexity is linear because the Morris Traversal algorithm traverses the tree in a single pass.
Auxiliary Space: The Auxiliary Space of the above code is O(1), as it does not use any extra space other than the variables used for traversing the tree.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads