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 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++
// 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> |
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.
Please Login to comment...