Inorder predecessor and successor in BST
Last Updated :
09 Jul, 2025
You are given root node of the BST and an integer key. You need to find the in-order successor and predecessor of the given key. If either predecessor or successor is not found, then set it to NULL.
Examples :
Input: root[] = [50, 30, 70, 20, 40, 60, 80], key = 65
Output: 60 70
Explanation: In given BST the inorder predecessor of 65 is 60 and inorder successor of 65 is 70
Input: root[] = [8, 1, 9, N, 4, N, 10, 3, N, N, N], key = 8

Output: 4 9
Explanation: In the given BST the inorder predecessor of 8 is 4 and inorder successor of 8 is 9.
[Naive Approach] Using Inorder Traversal - O(n) Time and O(n) Space
The idea is based on the fact that inorder traversal of a BST is always a sorted sequence. We do BST traversal, the first greater value seen is successor and the last smaller value seen is predecessor.
C++
#include <iostream>
#include <vector>
using namespace std;
class Node {
public:
int data;
Node *left, *right;
Node(int x) {
data = x;
left = right = nullptr;
}
};
// Function to find the predecessor and successor
// of a given key in BST and return them in a vector
vector<Node*> findPreSuc(Node* root, int key) {
vector<Node*> result;
Node* pre = nullptr;
Node* suc = nullptr;
// If root is null, return empty vector
if (!root)
return result;
// Traverse the tree
while (root != nullptr) {
if (root->data < key) {
// Current node is the predecessor
pre = root;
// Move to right subtree to find a larger node
root = root->right;
}
else if (root->data > key) {
// Current node is the successor
suc = root;
// Move to left subtree to find a smaller node
root = root->left;
}
else {
// When we find the node with the key, we can exit
if (root->left) {
Node* temp = root->left;
while (temp->right) temp = temp->right;
// The largest node in the left subtree is the predecessor
pre = temp;
}
if (root->right) {
Node* temp = root->right;
while (temp->left) temp = temp->left;
// The smallest node in the right subtree is the successor
suc = temp;
}
break;
}
}
// Push the predecessor and successor into the result vector
result.push_back(pre ? pre : nullptr);
result.push_back(suc ? suc : nullptr);
return result;
}
int main() {
int key = 65;
Node *root = new Node(50);
root->left = new Node(30);
root->right = new Node(70);
root->left->left = new Node(20);
root->left->right = new Node(40);
root->right->right = new Node(80);
root->right->left = new Node(60);
// Find predecessor and successor
vector<Node*> result = findPreSuc(root, key);
// Output the result
if (result[0] != nullptr)
cout << result[0]->data << " ";
else
cout << -1 << " ";
if (result[1] != nullptr)
cout << result[1]->data << endl;
else
cout << -1 << endl;
return 0;
}
Java
import java.util.ArrayList;
class Node {
int data;
Node left, right;
Node(int x) {
data = x;
left = right = null;
}
}
class GfG {
// Function to find predecessor and successor of a given key in BST
static ArrayList<Node> findPreSuc(Node root, int key) {
Node pre = null, suc = null;
Node current = root;
while (current != null) {
if (current.data < key) {
pre = current;
current = current.right;
} else if (current.data > key) {
suc = current;
current = current.left;
} else {
// Key found
if (current.left != null) {
Node temp = current.left;
while (temp.right != null)
temp = temp.right;
pre = temp;
}
if (current.right != null) {
Node temp = current.right;
while (temp.left != null)
temp = temp.left;
suc = temp;
}
break;
}
}
ArrayList<Node> result = new ArrayList<>();
// index 0 = predecessor
result.add(pre);
// index 1 = successor
result.add(suc);
return result;
}
public static void main(String[] args) {
int key = 65;
Node root = new Node(50);
root.left = new Node(30);
root.right = new Node(70);
root.left.left = new Node(20);
root.left.right = new Node(40);
root.right.left = new Node(60);
root.right.right = new Node(80);
ArrayList<Node> result = findPreSuc(root, key);
Node pre = result.get(0);
Node suc = result.get(1);
System.out.print((pre != null ? pre.data : -1) + " ");
System.out.println(suc != null ? suc.data : -1);
}
}
Python
class Node:
def __init__(self, x):
self.data = x
self.left = None
self.right = None
# Function to find predecessor and successor and return them in a list
def findPreSuc(root, key):
pre = None
suc = None
current = root
while current:
if current.data < key:
pre = current
current = current.right
elif current.data > key:
suc = current
current = current.left
else:
# If key is found
# Find predecessor (rightmost in left subtree)
if current.left:
temp = current.left
while temp.right:
temp = temp.right
pre = temp
# Find successor (leftmost in right subtree)
if current.right:
temp = current.right
while temp.left:
temp = temp.left
suc = temp
break
return [pre, suc]
if __name__ == "__main__":
key = 65
root = Node(50)
root.left = Node(30)
root.right = Node(70)
root.left.left = Node(20)
root.left.right = Node(40)
root.right.left = Node(60)
root.right.right = Node(80)
result = findPreSuc(root, key)
pre = result[0]
suc = result[1]
print(pre.data if pre else -1, end=" ")
print(suc.data if suc else -1)
C#
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node left, right;
public Node(int x) {
data = x;
left = right = null;
}
}
class GfG {
// Function to find predecessor and successor and return them in a List<Node>
static List<Node> FindPreSuc(Node root, int key) {
Node pre = null, suc = null;
Node current = root;
while (current != null) {
if (current.data < key) {
pre = current;
current = current.right;
} else if (current.data > key) {
suc = current;
current = current.left;
} else {
// Key found, now check left subtree for predecessor
if (current.left != null) {
Node temp = current.left;
while (temp.right != null)
temp = temp.right;
pre = temp;
}
// Check right subtree for successor
if (current.right != null) {
Node temp = current.right;
while (temp.left != null)
temp = temp.left;
suc = temp;
}
break;
}
}
return new List<Node> { pre, suc };
}
static void Main(string[] args) {
int key = 65;
Node root = new Node(50);
root.left = new Node(30);
root.right = new Node(70);
root.left.left = new Node(20);
root.left.right = new Node(40);
root.right.left = new Node(60);
root.right.right = new Node(80);
List<Node> result = FindPreSuc(root, key);
Node pre = result[0];
Node suc = result[1];
Console.Write((pre != null ? pre.data : -1) + " ");
Console.WriteLine(suc != null ? suc.data : -1);
}
}
JavaScript
class Node {
constructor(x) {
this.data = x;
this.left = null;
this.right = null;
}
}
// Function to find the predecessor and successor
// of a given key in BST and return them in a list
function findPreSuc(root, key) {
let pre = null;
let suc = null;
let current = root;
while (current !== null) {
if (current.data < key) {
pre = current;
current = current.right;
} else if (current.data > key) {
suc = current;
current = current.left;
} else {
// If key is found
// Find predecessor (rightmost in left subtree)
if (current.left !== null) {
let temp = current.left;
while (temp.right !== null) {
temp = temp.right;
}
pre = temp;
}
// Find successor (leftmost in right subtree)
if (current.right !== null) {
let temp = current.right;
while (temp.left !== null) {
temp = temp.left;
}
suc = temp;
}
break;
}
}
return [pre, suc];
}
// Driver Code
let key = 65;
let root = new Node(50);
root.left = new Node(30);
root.right = new Node(70);
root.left.left = new Node(20);
root.left.right = new Node(40);
root.right.left = new Node(60);
root.right.right = new Node(80);
// Call the function and get result
let [pre, suc] = findPreSuc(root, key);
console.log((pre ? pre.data : -1) + " " + (suc ? suc.data : -1));
[Expected Approach] Using BST Search - O(h) Time and O(1) Space
We have discussed Successor in BST. We use BST properties to efficiently find inorder successor and predecessor. We follow normal BST search algorithm. Before finding the given key, the last seen greater value is successor and the last seen smaller value is predecessor.
Follow the steps below to solve the problem:
- If root is NULL then return.
- if key is found then
- If its left subtree is not null, then predecessor will be the right most child of left subtree or left child itself.
- If its right subtree is not null Then The successor will be the left most child of right subtree or right child itself.
- If key is smaller than root node set the successor as root search recursively into left subtree.
- Otherwise set the predecessor as root search recursively into right subtree.
C++
#include <iostream>
#include <vector>
using namespace std;
class Node {
public:
int data;
Node *left, *right;
Node(int x) {
data = x;
left = right = nullptr;
}
};
Node* rightMost(Node* node) {
while (node->right != nullptr) {
node = node->right;
}
return node;
}
Node* leftMost(Node* node) {
while (node->left != nullptr) {
node = node->left;
}
return node;
}
// Return predecessor and successor as a vector<Node*>
vector<Node*> findPreSuc(Node* root, int key) {
Node* pre = nullptr;
Node* suc = nullptr;
Node* curr = root;
while (curr != nullptr) {
if (curr->data < key) {
pre = curr;
curr = curr->right;
} else if (curr->data > key) {
suc = curr;
curr = curr->left;
} else {
if (curr->left != nullptr)
pre = rightMost(curr->left);
if (curr->right != nullptr)
suc = leftMost(curr->right);
break;
}
}
return {pre, suc};
}
int main() {
int key = 65;
Node* root = new Node(50);
root->left = new Node(30);
root->right = new Node(70);
root->left->left = new Node(20);
root->left->right = new Node(40);
root->right->left = new Node(60);
root->right->right = new Node(80);
vector<Node*> result = findPreSuc(root, key);
Node* pre = result[0];
Node* suc = result[1];
if (pre != nullptr)
cout << pre->data << " ";
else
cout << -1 << " ";
if (suc != nullptr)
cout << suc->data << endl;
else
cout << -1 << endl;
return 0;
}
Java
import java.util.*;
class Node {
int data;
Node left, right;
Node(int x) {
data = x;
left = right = null;
}
}
class GfG {
static Node rightMost(Node node) {
while (node.right != null) {
node = node.right;
}
return node;
}
static Node leftMost(Node node) {
while (node.left != null) {
node = node.left;
}
return node;
}
// Return ArrayList with pre at index 0 and suc at index 1
static ArrayList<Node> findPreSuc(Node root, int key) {
Node pre = null, suc = null;
Node curr = root;
while (curr != null) {
if (curr.data < key) {
pre = curr;
curr = curr.right;
} else if (curr.data > key) {
suc = curr;
curr = curr.left;
} else {
if (curr.left != null)
pre = rightMost(curr.left);
if (curr.right != null)
suc = leftMost(curr.right);
break;
}
}
ArrayList<Node> result = new ArrayList<>();
result.add(pre); // index 0: predecessor
result.add(suc); // index 1: successor
return result;
}
public static void main(String[] args) {
int key = 65;
// Construct BST
Node root = new Node(50);
root.left = new Node(30);
root.right = new Node(70);
root.left.left = new Node(20);
root.left.right = new Node(40);
root.right.left = new Node(60);
root.right.right = new Node(80);
ArrayList<Node> result = findPreSuc(root, key);
Node pre = result.get(0);
Node suc = result.get(1);
if (pre != null)
System.out.print(pre.data + " ");
else
System.out.print("-1 ");
if (suc != null)
System.out.println(suc.data);
else
System.out.println("-1");
}
}
Python
class Node:
def __init__(self, x):
self.data = x
self.left = None
self.right = None
# Function to find maximum in left subtree (Predecessor)
def rightMost(node):
while node.right is not None:
node = node.right
return node
# Function to find minimum in right subtree (Successor)
def leftMost(node):
while node.left is not None:
node = node.left
return node
# Function to find predecessor and successor
def findPreSuc(root, key):
pre = None
suc = None
curr = root
while curr is not None:
if curr.data < key:
pre = curr
curr = curr.right
elif curr.data > key:
suc = curr
curr = curr.left
else:
# If key is found
if curr.left is not None:
pre = rightMost(curr.left)
if curr.right is not None:
suc = leftMost(curr.right)
break
return [pre, suc] # return as a list
# Main execution
if __name__ == "__main__":
key = 65
# Construct the BST
root = Node(50)
root.left = Node(30)
root.right = Node(70)
root.left.left = Node(20)
root.left.right = Node(40)
root.right.left = Node(60)
root.right.right = Node(80)
result = findPreSuc(root, key)
pre, suc = result[0], result[1]
if pre is not None:
print(pre.data, end=" ")
else:
print(-1, end=" ")
if suc is not None:
print(suc.data)
else:
print(-1)
C#
using System;
using System.Collections.Generic;
// Definition of a node in the Binary Search Tree (BST)
class Node {
public int data;
public Node left, right;
public Node(int x) {
data = x;
left = right = null;
}
}
class GfG {
// Finds the rightmost (maximum value) node in the given subtree
static Node rightMost(Node node) {
while (node.right != null) {
node = node.right;
}
return node;
}
// Finds the leftmost (minimum value) node in the given subtree
static Node leftMost(Node node) {
while (node.left != null) {
node = node.left;
}
return node;
}
// Finds and returns the predecessor and successor of a given key
// in a BST Returns a list
static List<Node> findPreSuc(Node root, int key) {
Node pre = null, suc = null;
Node curr = root;
// Traverse the tree to find the key and track potential pre/suc
while (curr != null) {
if (curr.data < key) {
pre = curr;
curr = curr.right;
} else if (curr.data > key) {
suc = curr;
curr = curr.left;
} else {
// If the key is found, find the actual predecessor
// and successor
if (curr.left != null)
// Max in left subtree
pre = rightMost(curr.left);
if (curr.right != null)
// Min in right subtree
suc = leftMost(curr.right);
break;
}
}
return new List<Node> { pre, suc };
}
static void Main() {
int key = 65;
Node root = new Node(50);
root.left = new Node(30);
root.right = new Node(70);
root.left.left = new Node(20);
root.left.right = new Node(40);
root.right.left = new Node(60);
root.right.right = new Node(80);
// Get the predecessor and successor
List<Node> result = findPreSuc(root, key);
Node pre = result[0];
Node suc = result[1];
// Output predecessor
if (pre != null)
Console.Write(pre.data + " ");
else
Console.Write("-1 ");
// Output successor
if (suc != null)
Console.WriteLine(suc.data);
else
Console.WriteLine("-1");
}
}
JavaScript
class Node {
constructor(x) {
this.data = x;
this.left = null;
this.right = null;
}
}
// Returns the rightmost (maximum) node in a subtree
function rightMost(node) {
while (node.right !== null) {
node = node.right;
}
return node;
}
// Returns the leftmost (minimum) node in a subtree
function leftMost(node) {
while (node.left !== null) {
node = node.left;
}
return node;
}
// Finds and returns [predecessor, successor]
// of a given key in the BST
function findPreSuc(root, key) {
let pre = null, suc = null;
let curr = root;
while (curr !== null) {
if (curr.data < key) {
pre = curr;
curr = curr.right;
} else if (curr.data > key) {
suc = curr;
curr = curr.left;
} else {
if (curr.left !== null) {
pre = rightMost(curr.left);
}
if (curr.right !== null) {
suc = leftMost(curr.right);
}
break;
}
}
return [pre, suc];
}
// Driver Code
let key = 65;
let root = new Node(50);
root.left = new Node(30);
root.right = new Node(70);
root.left.left = new Node(20);
root.left.right = new Node(40);
root.right.left = new Node(60);
root.right.right = new Node(80);
// Get predecessor and successor
let [pre, suc] = findPreSuc(root, key);
// Print results
if (pre !== null)
process.stdout.write(pre.data + " ");
else
process.stdout.write("-1 ");
if (suc !== null)
console.log(suc.data);
else
console.log(-1);
Inorder predecessor and successor for a given key in BST
Similar Reads
Binary Search Tree A Binary Search Tree (BST) is a type of binary tree data structure in which each node contains a unique key and satisfies a specific ordering property:All nodes in the left subtree of a node contain values strictly less than the nodeâs value. All nodes in the right subtree of a node contain values s
4 min read
Introduction to Binary Search Tree Binary Search Tree is a data structure used in computer science for organizing and storing data in a sorted manner. Binary search tree follows all properties of binary tree and for every nodes, its left subtree contains values less than the node and the right subtree contains values greater than the
3 min read
Applications of BST Binary Search Tree (BST) is a data structure that is commonly used to implement efficient searching, insertion, and deletion operations along with maintaining sorted sequence of data. Please remember the following properties of BSTs before moving forward.The left subtree of a node contains only node
3 min read
Applications, Advantages and Disadvantages of Binary Search Tree A Binary Search Tree (BST) is a data structure used to storing data in a sorted manner. Each node in a Binary Search Tree has at most two children, a left child and a right child, with the left child containing values less than the parent node and the right child containing values greater than the p
2 min read
Insertion in Binary Search Tree (BST) Given a BST, the task is to insert a new node in this BST.Example: How to Insert a value in a Binary Search Tree:A new key is always inserted at the leaf by maintaining the property of the binary search tree. We start searching for a key from the root until we hit a leaf node. Once a leaf node is fo
15 min read
Searching in Binary Search Tree (BST) Given a BST, the task is to search a node in this BST. For searching a value in BST, consider it as a sorted array. Now we can easily perform search operation in BST using Binary Search Algorithm. Input: Root of the below BST Output: TrueExplanation: 8 is present in the BST as right child of rootInp
7 min read
Deletion in Binary Search Tree (BST) Given a BST, the task is to delete a node in this BST, which can be broken down into 3 scenarios:Case 1. Delete a Leaf Node in BST Case 2. Delete a Node with Single Child in BSTDeleting a single child node is also simple in BST. Copy the child to the node and delete the node. Case 3. Delete a Node w
10 min read
Binary Search Tree (BST) Traversals â Inorder, Preorder, Post Order Given a Binary Search Tree, The task is to print the elements in inorder, preorder, and postorder traversal of the Binary Search Tree. Input: A Binary Search TreeOutput: Inorder Traversal: 10 20 30 100 150 200 300Preorder Traversal: 100 20 10 30 200 150 300Postorder Traversal: 10 30 20 150 300 200 1
10 min read
Balance a Binary Search Tree Given a BST (Binary Search Tree) that may be unbalanced, the task is to convert it into a balanced BST that has the minimum possible height.Examples: Input: Output: Explanation: The above unbalanced BST is converted to balanced with the minimum possible height.Input: Output: Explanation: The above u
10 min read
Self-Balancing Binary Search Trees Self-Balancing Binary Search Trees are height-balanced binary search trees that automatically keep the height as small as possible when insertion and deletion operations are performed on the tree. The height is typically maintained in order of logN so that all operations take O(logN) time on average
4 min read