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 9P = 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 / 23P = 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++ 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 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 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# 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 |
<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> |
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.