Inorder predecessor in Binary Tree
Last Updated :
26 Oct, 2024
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 7 is 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>
using namespace std;
class Node {
public:
int data;
Node* left;
Node* right;
Node(int val) {
data = val;
left = nullptr;
right = nullptr;
}
};
// Function to find the inorder predecessor
// of a target value.
Node* getPred(Node* root, int target, Node*& last) {
if (!root) return nullptr;
// Search in the left subtree
Node* pred = getPred(root->left, target, last);
// If the predecessor is found in the
// right subtree, return it
if (pred) return pred;
// If root's data matches the target,
// return the last visited node
if (root->data == target)
return last;
// Mark the current node as last visited
last = root;
// Search in the left subtree
return getPred(root->right, target, last);
}
int main() {
// Let's construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node* root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);
root->right->left = new Node(6);
root->right->right = new Node(7);
int target = 3;
Node* last = nullptr;
Node* pred = getPred(root, target, last);
if (pred)
cout << pred->data << endl;
else
cout << "null" << endl;
return 0;
}
Java
// Java program to find the inorder predecessor
// of a target value in a binary tree.
class Node {
int data;
Node left, right;
// Constructor to initialize a new Node.
Node(int val) {
data = val;
left = null;
right = null;
}
}
class GfG {
// Function to find the inorder predecessor of a target value.
static Node getPred(Node root, int target, Node[] last) {
if (root == null) return null;
// Search in the right subtree
Node pred = getPred(root.left, target, last);
// If the predecessor is found in the right subtree, return it
if (pred != null) return pred;
// If root's data matches the target,
// return the last visited node
if (root.data == target)
return last[0];
// Mark the current node as last visited
last[0] = root;
// Search in the left subtree
return getPred(root.right, target, last);
}
public static void main(String[] args) {
// Let's construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
// Target node value for which we need to find the predecessor
int target = 3;
Node[] last = new Node[1];
Node pred = getPred(root, target, last);
if (pred != null)
System.out.println(pred.data);
else
System.out.println("null");
}
}
Python
# Python program to find the inorder predecessor
# of a target value in a binary tree.
class Node:
def __init__(self, val):
self.data = val
self.left = None
self.right = None
def getPred(root, target, last):
if not root:
return None
# Search in the right subtree
pred = getPred(root.left, target, last)
# If the predecessor is found in the right subtree, return it
if pred:
return pred
# If root's data matches the target, return the last visited node
if root.data == target:
return last[0]
# Mark the current node as last visited
last[0] = root
# Search in the left subtree
return getPred(root.right, target, last)
if __name__ == "__main__":
# Let's construct the binary tree
# 1
# / \
# 2 3
# / \ / \
# 4 5 6 7
root = 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 predecessor
target = 3
last = [None]
pred = getPred(root, target, last)
if pred:
print(pred.data)
else:
print("null")
C#
// C# program to find the inorder predecessor
// of a target value in a binary tree.
using System;
class Node {
public int data;
public Node left, right;
// Constructor to initialize a new Node.
public Node(int val) {
data = val;
left = null;
right = null;
}
}
class GfG {
// Function to find the inorder predecessor of a target value.
static Node GetPred(Node root, int target, ref Node last) {
if (root == null) return null;
// Search in the right subtree
Node pred = GetPred(root.left, target, ref last);
// If the predecessor is found in the right subtree, return it
if (pred != null) return pred;
// If root's data matches the target, return the last visited node
if (root.data == target)
return last;
// Mark the current node as last visited
last = root;
// Search in the left subtree
return GetPred(root.right, target, ref last);
}
public static void Main() {
// Let's construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
// Target node value for which we need to find the predecessor
int target = 3;
Node last = null;
Node pred = GetPred(root, target, ref last);
if (pred != null)
Console.WriteLine(pred.data);
else
Console.WriteLine("null");
}
}
JavaScript
// JavaScript program to find the inorder predecessor
// of a target value in a binary tree.
class Node {
constructor(val) {
this.data = val;
this.left = null;
this.right = null;
}
}
function getPred(root, target, last) {
if (!root) return null;
// Search in the right subtree
let pred = getPred(root.left, target, last);
// If the predecessor is found in the right subtree, return it
if (pred) return pred;
// If root's data matches the target, return the last visited node
if (root.data === target)
return last[0];
// Mark the current node as last visited
last[0] = root;
// Search in the left subtree
return getPred(root.right, target, last);
}
// Driver Code
const main = () => {
// Let's construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
let root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
// Target node value for which we need to find the predecessor
let target = 3;
let last = [null];
let pred = getPred(root, target, last);
if (pred)
console.log(pred.data);
else
console.log("null");
};
main();
[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>
using namespace std;
class Node {
public:
int data;
Node* left;
Node* right;
Node(int val) {
data = val;
left = nullptr;
right = nullptr;
}
};
// Function to find the inorder predecessor of
// a target value using Morris traversal.
Node* getPred(Node* root, int target) {
Node* curr = root;
Node* predecessor = nullptr;
bool targetFound = false;
while (curr != nullptr) {
if (curr->right == nullptr) {
if (targetFound) {
// Return the predecessor if
// target has been found
return curr;
}
if (curr->data == target) {
targetFound = true;
}
curr = curr->left;
} else {
// Find the inorder predecessor of curr
Node* 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 predecessor
pred->left = curr;
curr = curr->right;
} else {
// Revert the changes made in the 'if' part
// to restore the original tree
pred->left = nullptr;
if (targetFound) {
// Return the predecessor if target
// has been found
return curr;
}
if (curr->data == target) {
targetFound = true;
}
curr = curr->left;
}
}
}
return nullptr;
}
int main() {
// Let's construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node* root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);
root->right->left = new Node(6);
root->right->right = new Node(7);
int target = 3;
Node* pred = getPred(root, target);
if (pred)
cout << pred->data << endl;
else
cout << "null" << endl;
return 0;
}
Java
// Java code to find Inorder predecessor
// using Morris traversal.
class Node {
int data;
Node left, right;
Node(int val) {
data = val;
left = right = null;
}
}
class GfG {
// Function to find the inorder predecessor of
// a target value using Morris traversal.
static Node getPred(Node root, int target) {
Node curr = root;
Node predecessor = null;
boolean targetFound = false;
while (curr != null) {
if (curr.right == null) {
if (targetFound) {
// Return the predecessor
// if target has been found
return curr;
}
if (curr.data == target) {
targetFound = true;
}
curr = curr.left;
} else {
// Find the inorder predecessor
// of curr
Node pred = curr.right;
while (pred.left != null && pred.left != curr) {
pred = pred.left;
}
if (pred.left == null) {
// Make curr the left child of
// its inorder predecessor
pred.left = curr;
curr = curr.right;
} else {
// Revert the changes made in the 'if' part
// to restore the original tree
pred.left = null;
if (targetFound) {
// Return the predecessor if target
// has been found
return curr;
}
if (curr.data == target) {
targetFound = true;
}
curr = curr.left;
}
}
}
return null;
}
public static void main(String[] args) {
// Let's construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
int target = 3;
Node pred = getPred(root, target);
if (pred != null)
System.out.println(pred.data);
else
System.out.println("null");
}
}
Python
# Python code to find Inorder predecessor
# using Morris traversal.
class Node:
def __init__(self, val):
self.data = val
self.left = None
self.right = None
# Function to find the inorder predecessor of
# a target value using Morris traversal.
def getPred(root, target):
curr = root
predecessor = None
targetFound = False
while curr is not None:
if curr.right is None:
if targetFound:
# Return the predecessor if target
# has been found
return curr
if curr.data == target:
targetFound = True
curr = curr.left
else:
# Find the inorder predecessor
# of curr
pred = curr.right
while pred.left is not None and pred.left != curr:
pred = pred.left
if pred.left is None:
# Make curr the left child of its
# inorder predecessor
pred.left = curr
curr = curr.right
else:
# Revert the changes made in the 'if' part
# to restore the original tree
pred.left = None
if targetFound:
# Return the predecessor if
# target has been found
return curr
if curr.data == target:
# Mark that the target
# is found
targetFound = True
# Move to left subtree
curr = curr.left
return None
if __name__ == "__main__":
# Let's construct the binary tree
# 1
# / \
# 2 3
# / \ / \
# 4 5 6 7
root = 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 = 3
pred = getPred(root, target)
if pred:
print(pred.data)
else:
print("null")
C#
// C# code to find Inorder predecessor using
// Morris traversal.
using System;
class Node {
public int data;
public Node left, right;
public Node(int val) {
data = val;
left = right = null;
}
}
class GfG {
// Function to find the inorder predecessor of
// a target value using Morris traversal.
static Node getPred(Node root, int target) {
Node curr = root;
bool targetFound = false;
while (curr != null) {
if (curr.right == null) {
if (targetFound) {
// Return the predecessor if
// target has been found
return curr;
}
if (curr.data == target) {
targetFound = true;
}
curr = curr.left;
}
else {
// Find the inorder predecessor
// of curr
Node pred = curr.right;
while (pred.left != null
&& pred.left != curr) {
pred = pred.left;
}
if (pred.left == null) {
// Make curr the left child of its
// inorder predecessor
pred.left = curr;
curr = curr.right;
}
else {
// Revert the changes made in the 'if'
// part to restore the original tree
pred.left = null;
if (targetFound) {
// Return the predecessor if target
// has been found
return curr;
}
if (curr.data == target) {
// Mark that the target is found
targetFound = true;
}
curr = curr.left;
}
}
}
return null;
}
static void Main(string[] args) {
// Let's construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
int target = 3;
Node pred = getPred(root, target);
if (pred != null)
Console.WriteLine(pred.data);
else
Console.WriteLine("null");
}
}
JavaScript
// JavaScript code to find Inorder predecessor
// using Morris traversal.
class Node {
constructor(val) {
this.data = val;
this.left = null;
this.right = null;
}
}
// Function to find the inorder predecessor of
// a target value using Morris traversal.
function getPred(root, target) {
let curr = root;
let targetFound = false;
while (curr !== null) {
if (curr.right === null) {
if (targetFound) {
// Return the predecessor if target
// has been found
return curr;
}
if (curr.data === target) {
targetFound = true;
}
curr = curr.left;
} else {
// Find the inorder predecessor
// of curr
let pred = curr.right;
while (pred.left !== null && pred.left !== curr) {
pred = pred.left;
}
if (pred.left === null) {
// Make curr the left child of its
// inorder predecessor
pred.left = curr;
curr = curr.right;
} else {
// Revert the changes made in the 'if' part
// to restore the original tree
pred.left = null;
if (targetFound) {
// Return the predecessor if target
// has been found
return curr;
}
if (curr.data === target) {
targetFound = true;
}
curr = curr.left;
}
}
}
return null;
}
// Let's construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
let root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
let target = 3;
let pred = getPred(root, target);
if (pred) {
console.log(pred.data);
} else {
console.log("null");
}
Related articles:
Similar Reads
Inorder predecessor in Binary Search Tree Given a Binary Search Tree, the task is to find the In-Order predecessor of a given target key.In a Binary Search Tree (BST), the Inorder predecessor of a node is the previous node in the Inorder traversal of the BST. The Inorder predecessor is NULL for the first node in the Inorder traversal.Exampl
10 min read
Inorder successor in Binary Tree Given a binary tree and a node, the task is to find the inorder successor of this node. Inorder Successor of a node in the binary tree is the next node in the Inorder traversal of the Binary Tree. Inorder Successor is NULL for the last node in Inorder traversal. In the below diagram, inorder success
15 min read
Preorder Successor of a Node in Binary Tree Given a binary tree and a node in the binary tree, find the preorder successor of the given node. It may be assumed that every node has a parent link. Examples: Consider the following binary tree 20 / \ 10 26 / \ / \ 4 18 24 27 / \ 14 19 / \ 13 15 Input : 4 Output : 18 Preorder traversal of given tr
9 min read
Level Order Predecessor of a node in Binary Tree Given a binary tree and a node in the binary tree, find Levelorder Predecessor of the given node. That is, the node that appears before the given node in the level order traversal of the tree. Note: The task is not just to print the data of the node, you have to return the complete node from the tre
8 min read
Preorder predecessor of a Node in Binary Tree Given the root of a binary tree and a node of a binary tree, the task is to find the preorder predecessor of the given node. Note: Print -1, if the preorder predecessor of the given node do not exists.Examples: Consider the following binary treeInput: node = 4Output: 10Explanation: Preorder traversa
14 min read
Postorder successor of a Node in Binary Tree Given a binary tree and a node in the binary tree, find Postorder successor of the given node. Examples: Consider the following binary tree 20 / \ 10 26 / \ / \ 4 18 24 27 / \ 14 19 / \ 13 15 Postorder traversal of given tree is 4, 13, 15, 14, 19, 18, 10, 24, 27, 26, 20. Input : Complexity Analysis:
8 min read
Postorder predecessor of a Node in Binary Search Tree Given a binary tree and a node in the binary tree, find the Postorder predecessor of the given node. Examples: Consider the following binary tree 20 / \ 10 26 / \ / \ 4 18 24 27 / \ 14 19 / \ 13 15 Input : 4 Output : 10 Postorder traversal of given tree is 4, 13, 15, 14, 19, 18, 10, 24, 27, 26, 20.
8 min read
Pre-Order Successor of all nodes in Binary Search Tree Consider a BST(Binary Search Tree) where duplicates are not allowed.Given a key present in the BST. The task is to find its pre-order successor in this BST i.e. the task is to find a key that comes next to the given key if we apply a pre-order traversal on given BST. Example: Insert the following ke
15+ min read
Level Order Successor of a node in Binary Tree Given a binary tree and a node in the binary tree, find Levelorder successor of the given node. That is, the node that appears after the given node in the level order traversal of the tree. Note: The task is not just to print the data of the node, you have to return the complete node from the tree.
9 min read
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 In
10 min read