Open In App

Inorder predecessor and successor in BST

Last Updated : 09 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

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

12

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));

Output
60 70

[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);

Output
60 70

Inorder predecessor and successor for a given key in BST

Similar Reads