In the Binary Tree, the Inorder predecessor of a node is the previous node in the Inorder traversal of the Binary Tree. The Inorder Predecessor is NULL for the first node in Inorder traversal.
Example:
In the below diagram, inorder predecessor of node 7is 3 , node 2 is 7 and node 4 is null.
[Naive approach] Using Reverse Inorder - O(n) Time and O(h) Space
To find the inorder predecessor of a target node, we perform a reverse inorder traversal while keeping track of the last visited node. As we traverse, if we locate the target node, we check its left subtree for the predecessor; if found, we return it. If the current root's data matches the target, we return the last visited node from the left subtree as the predecessor. During each step, we update the last visited node and proceed to recursively explore the right subtree, continuing this process until we find the predecessor or complete the traversal.
Below is the implementation of the above approach:
C++
//C++ implemenataton to find Inorder predecessor//in Binary Serach Tree#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=nullptr;right=nullptr;}};// Function to find the inorder predecessor // of a target value.Node*getPred(Node*root,inttarget,Node*&last){if(!root)returnnullptr;// Search in the left subtreeNode*pred=getPred(root->left,target,last);// If the predecessor is found in the // right subtree, return itif(pred)returnpred;// If root's data matches the target, // return the last visited nodeif(root->data==target)returnlast;// Mark the current node as last visitedlast=root;// Search in the left subtreereturngetPred(root->right,target,last);}intmain(){// Let's construct the binary tree // 1// / \ // 2 3// / \ / \ // 4 5 6 7Node*root=newNode(1);root->left=newNode(2);root->right=newNode(3);root->left->left=newNode(4);root->left->right=newNode(5);root->right->left=newNode(6);root->right->right=newNode(7);inttarget=3;Node*last=nullptr;Node*pred=getPred(root,target,last);if(pred)cout<<pred->data<<endl;elsecout<<"null"<<endl;return0;}
Java
// Java program to find the inorder predecessor// of a target value in a binary tree.classNode{intdata;Nodeleft,right;// Constructor to initialize a new Node.Node(intval){data=val;left=null;right=null;}}classGfG{// Function to find the inorder predecessor of a target value.staticNodegetPred(Noderoot,inttarget,Node[]last){if(root==null)returnnull;// Search in the right subtreeNodepred=getPred(root.left,target,last);// If the predecessor is found in the right subtree, return itif(pred!=null)returnpred;// If root's data matches the target, // return the last visited nodeif(root.data==target)returnlast[0];// Mark the current node as last visitedlast[0]=root;// Search in the left subtreereturngetPred(root.right,target,last);}publicstaticvoidmain(String[]args){// Let's construct the binary tree // 1// / \// 2 3// / \ / \// 4 5 6 7Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);root.right.left=newNode(6);root.right.right=newNode(7);// Target node value for which we need to find the predecessorinttarget=3;Node[]last=newNode[1];Nodepred=getPred(root,target,last);if(pred!=null)System.out.println(pred.data);elseSystem.out.println("null");}}
Python
# Python program to find the inorder predecessor # of a target value in a binary tree.classNode:def__init__(self,val):self.data=valself.left=Noneself.right=NonedefgetPred(root,target,last):ifnotroot:returnNone# Search in the right subtreepred=getPred(root.left,target,last)# If the predecessor is found in the right subtree, return itifpred:returnpred# If root's data matches the target, return the last visited nodeifroot.data==target:returnlast[0]# Mark the current node as last visitedlast[0]=root# Search in the left subtreereturngetPred(root.right,target,last)if__name__=="__main__":# Let's construct the binary tree # 1# / \# 2 3# / \ / \# 4 5 6 7root=Node(1)root.left=Node(2)root.right=Node(3)root.left.left=Node(4)root.left.right=Node(5)root.right.left=Node(6)root.right.right=Node(7)# Target node value for which we need to find the predecessortarget=3last=[None]pred=getPred(root,target,last)ifpred:print(pred.data)else:print("null")
C#
// C# program to find the inorder predecessor// of a target value in a binary tree.usingSystem;classNode{publicintdata;publicNodeleft,right;// Constructor to initialize a new Node.publicNode(intval){data=val;left=null;right=null;}}classGfG{// Function to find the inorder predecessor of a target value.staticNodeGetPred(Noderoot,inttarget,refNodelast){if(root==null)returnnull;// Search in the right subtreeNodepred=GetPred(root.left,target,reflast);// If the predecessor is found in the right subtree, return itif(pred!=null)returnpred;// If root's data matches the target, return the last visited nodeif(root.data==target)returnlast;// Mark the current node as last visitedlast=root;// Search in the left subtreereturnGetPred(root.right,target,reflast);}publicstaticvoidMain(){// Let's construct the binary tree // 1// / \// 2 3// / \ / \// 4 5 6 7Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);root.right.left=newNode(6);root.right.right=newNode(7);// Target node value for which we need to find the predecessorinttarget=3;Nodelast=null;Nodepred=GetPred(root,target,reflast);if(pred!=null)Console.WriteLine(pred.data);elseConsole.WriteLine("null");}}
JavaScript
// JavaScript program to find the inorder predecessor // of a target value in a binary tree.classNode{constructor(val){this.data=val;this.left=null;this.right=null;}}functiongetPred(root,target,last){if(!root)returnnull;// Search in the right subtreeletpred=getPred(root.left,target,last);// If the predecessor is found in the right subtree, return itif(pred)returnpred;// If root's data matches the target, return the last visited nodeif(root.data===target)returnlast[0];// Mark the current node as last visitedlast[0]=root;// Search in the left subtreereturngetPred(root.right,target,last);}// Driver Codeconstmain=()=>{// Let's construct the binary tree // 1// / \// 2 3// / \ / \// 4 5 6 7letroot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);root.right.left=newNode(6);root.right.right=newNode(7);// Target node value for which we need to find the predecessorlettarget=3;letlast=[null];letpred=getPred(root,target,last);if(pred)console.log(pred.data);elseconsole.log("null");};main();
Output
6
[Expected approach] Using Morris Traversal - O(n) Time and O(1) Space
We can optimize the auxiliary space of above approach used using Morris Traversal (A standard technique to do inorder traversal without stack and recursion).
Below is the implementation of the above approach:
C++
// C++ code to find Inorder predecessor// using Morris traversal.#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=nullptr;right=nullptr;}};// Function to find the inorder predecessor of// a target value using Morris traversal.Node*getPred(Node*root,inttarget){Node*curr=root;Node*predecessor=nullptr;booltargetFound=false;while(curr!=nullptr){if(curr->right==nullptr){if(targetFound){// Return the predecessor if // target has been foundreturncurr;}if(curr->data==target){targetFound=true;}curr=curr->left;}else{// Find the inorder predecessor of currNode*pred=curr->right;while(pred->left!=nullptr&&pred->left!=curr){pred=pred->left;}if(pred->left==nullptr){// Make curr the left child of its// inorder predecessorpred->left=curr;curr=curr->right;}else{// Revert the changes made in the 'if' part // to restore the original treepred->left=nullptr;if(targetFound){// Return the predecessor if target // has been foundreturncurr;}if(curr->data==target){targetFound=true;}curr=curr->left;}}}returnnullptr;}intmain(){// Let's construct the binary tree // 1// / \ // 2 3// / \ / \ // 4 5 6 7Node*root=newNode(1);root->left=newNode(2);root->right=newNode(3);root->left->left=newNode(4);root->left->right=newNode(5);root->right->left=newNode(6);root->right->right=newNode(7);inttarget=3;Node*pred=getPred(root,target);if(pred)cout<<pred->data<<endl;elsecout<<"null"<<endl;return0;}
Java
// Java code to find Inorder predecessor// using Morris traversal.classNode{intdata;Nodeleft,right;Node(intval){data=val;left=right=null;}}classGfG{// Function to find the inorder predecessor of// a target value using Morris traversal.staticNodegetPred(Noderoot,inttarget){Nodecurr=root;Nodepredecessor=null;booleantargetFound=false;while(curr!=null){if(curr.right==null){if(targetFound){// Return the predecessor// if target has been foundreturncurr;}if(curr.data==target){targetFound=true;}curr=curr.left;}else{// Find the inorder predecessor // of currNodepred=curr.right;while(pred.left!=null&&pred.left!=curr){pred=pred.left;}if(pred.left==null){// Make curr the left child of// its inorder predecessorpred.left=curr;curr=curr.right;}else{// Revert the changes made in the 'if' part// to restore the original treepred.left=null;if(targetFound){// Return the predecessor if target// has been foundreturncurr;}if(curr.data==target){targetFound=true;}curr=curr.left;}}}returnnull;}publicstaticvoidmain(String[]args){// Let's construct the binary tree // 1// / \// 2 3// / \ / \// 4 5 6 7Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);root.right.left=newNode(6);root.right.right=newNode(7);inttarget=3;Nodepred=getPred(root,target);if(pred!=null)System.out.println(pred.data);elseSystem.out.println("null");}}
Python
# Python code to find Inorder predecessor# using Morris traversal.classNode:def__init__(self,val):self.data=valself.left=Noneself.right=None# Function to find the inorder predecessor of# a target value using Morris traversal.defgetPred(root,target):curr=rootpredecessor=NonetargetFound=FalsewhilecurrisnotNone:ifcurr.rightisNone:iftargetFound:# Return the predecessor if target # has been foundreturncurrifcurr.data==target:targetFound=Truecurr=curr.leftelse:# Find the inorder predecessor# of currpred=curr.rightwhilepred.leftisnotNoneandpred.left!=curr:pred=pred.leftifpred.leftisNone:# Make curr the left child of its # inorder predecessorpred.left=currcurr=curr.rightelse:# Revert the changes made in the 'if' part# to restore the original treepred.left=NoneiftargetFound:# Return the predecessor if # target has been foundreturncurrifcurr.data==target:# Mark that the target# is foundtargetFound=True# Move to left subtreecurr=curr.leftreturnNoneif__name__=="__main__":# Let's construct the binary tree # 1# / \# 2 3# / \ / \# 4 5 6 7root=Node(1)root.left=Node(2)root.right=Node(3)root.left.left=Node(4)root.left.right=Node(5)root.right.left=Node(6)root.right.right=Node(7)target=3pred=getPred(root,target)ifpred:print(pred.data)else:print("null")
C#
// C# code to find Inorder predecessor using// Morris traversal.usingSystem;classNode{publicintdata;publicNodeleft,right;publicNode(intval){data=val;left=right=null;}}classGfG{// Function to find the inorder predecessor of// a target value using Morris traversal.staticNodegetPred(Noderoot,inttarget){Nodecurr=root;booltargetFound=false;while(curr!=null){if(curr.right==null){if(targetFound){// Return the predecessor if// target has been foundreturncurr;}if(curr.data==target){targetFound=true;}curr=curr.left;}else{// Find the inorder predecessor // of currNodepred=curr.right;while(pred.left!=null&&pred.left!=curr){pred=pred.left;}if(pred.left==null){// Make curr the left child of its// inorder predecessorpred.left=curr;curr=curr.right;}else{// Revert the changes made in the 'if'// part to restore the original treepred.left=null;if(targetFound){// Return the predecessor if target// has been foundreturncurr;}if(curr.data==target){// Mark that the target is foundtargetFound=true;}curr=curr.left;}}}returnnull;}staticvoidMain(string[]args){// Let's construct the binary tree// 1// / \// 2 3// / \ / \// 4 5 6 7Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);root.right.left=newNode(6);root.right.right=newNode(7);inttarget=3;Nodepred=getPred(root,target);if(pred!=null)Console.WriteLine(pred.data);elseConsole.WriteLine("null");}}
JavaScript
// JavaScript code to find Inorder predecessor // using Morris traversal.classNode{constructor(val){this.data=val;this.left=null;this.right=null;}}// Function to find the inorder predecessor of// a target value using Morris traversal.functiongetPred(root,target){letcurr=root;lettargetFound=false;while(curr!==null){if(curr.right===null){if(targetFound){// Return the predecessor if target// has been foundreturncurr;}if(curr.data===target){targetFound=true;}curr=curr.left;}else{// Find the inorder predecessor// of currletpred=curr.right;while(pred.left!==null&&pred.left!==curr){pred=pred.left;}if(pred.left===null){// Make curr the left child of its// inorder predecessorpred.left=curr;curr=curr.right;}else{// Revert the changes made in the 'if' part// to restore the original treepred.left=null;if(targetFound){// Return the predecessor if target // has been foundreturncurr;}if(curr.data===target){targetFound=true;}curr=curr.left;}}}returnnull;}// Let's construct the binary tree // 1// / \// 2 3// / \ / \// 4 5 6 7letroot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);root.right.left=newNode(6);root.right.right=newNode(7);lettarget=3;letpred=getPred(root,target);if(pred){console.log(pred.data);}else{console.log("null");}