K'th Largest Element in BST

Last Updated : 18 Jul, 2026

Given the root of a Binary Search Tree (BST) and an integer k, find the k-th largest element in the BST without modifying its structure.

Examples: 

Input: root = [4, 2, 9], k = 2

1

Output: 4
Explanation: The second largest element is 4.

Input: root = [10, 2, 11, 1, 5, N, N, N, N, 3, 6, N, 4], k = 7

2

Output: 2
Explanation: The 7th largest element is 2.

Input: root = [4, 2, 9], k = 3

3

Output: 2
Explanation: The 3rd largest element is 2.

Try It Yourself
redirect icon

Using Recursion - O(n) Time and O(h) Space

The idea is to traverse the binary search tree in reverse in-order manner. This way we will traverse the elements in decreasing order. Maintain the count of nodes traversed so far. If count becomes equal to k, return the element.

Working of Approach:

  • Traverse the BST in reverse inorder (Right -> Root -> Left) using recursion.
  • First recursively visit the right subtree, as it contains the larger elements.
  • After visiting a node, increment the count of visited nodes.
  • If the count becomes equal to k, return the current node as the k-th largest element.
  • Otherwise, recursively traverse the left subtree until the required node is found or the traversal is complete.
C++
// C++ Program to find kth largest element
#include <bits/stdc++.h>
using namespace std;

class Node
{
  public:
    int data;
    Node *left;
    Node *right;
    Node(int x)
    {
        data = x;
        left = right = nullptr;
    }
};

// Function which will traverse the BST
// in reverse inorder manner.
int kthLargestRecur(Node *root, int &cnt, int k)
{

    // base case
    if (root == nullptr)
        return -1;

    int right = kthLargestRecur(root->right, cnt, k);

    // if kth largest number is present in
    // right subtree, then return it.
    if (right != -1)
        return right;

    // Increment the node count.
    cnt++;

    // If root node is the kth largest element,
    // then return it.
    if (cnt == k)
        return root->data;

    int left = kthLargestRecur(root->left, cnt, k);

    // else return value provided by
    // left subtree.
    return left;
}

int kthLargest(Node *root, int k)
{
    int cnt = 0;
    return kthLargestRecur(root, cnt, k);
}

int main()
{
    // Create the following BST:
    //
    //          10
    //         /  \
    //        2    11
    //       / \
    //      1   5
    //         / \
    //        3   6
    //         \
    //          4
    //

    Node *root = new Node(10);
    root->left = new Node(2);
    root->right = new Node(11);

    root->left->left = new Node(1);
    root->left->right = new Node(5);

    root->left->right->left = new Node(3);
    root->left->right->right = new Node(6);

    root->left->right->left->right = new Node(4);

    int k = 7;

    cout << kthLargest(root, k);

    return 0;
}
Java
class Node {
    int data;
    Node left;
    Node right;

    Node(int x)
    {
        data = x;
        left = right = null;
    }
}

class GFG {

    // Function which will traverse the BST
    // in reverse inorder manner.
    static int kthLargestRecur(Node root, int[] cnt, int k)
    {

        // Base case
        if (root == null)
            return -1;

        int right = kthLargestRecur(root.right, cnt, k);

        // If kth largest number is present in
        // right subtree, then return it.
        if (right != -1)
            return right;

        // Increment the node count.
        cnt[0]++;

        // If root node is the kth largest element,
        // then return it.
        if (cnt[0] == k)
            return root.data;

        int left = kthLargestRecur(root.left, cnt, k);

        // Else return value provided by
        // left subtree.
        return left;
    }

    static int kthLargest(Node root, int k)
    {
        int[] cnt = { 0 };
        return kthLargestRecur(root, cnt, k);
    }

    public static void main(String[] args)
    {

        // Create the following BST:
        //
        //          10
        //         /  \
        //        2    11
        //       / \
        //      1   5
        //         / \
        //        3   6
        //         \
        //          4
        //

        Node root = new Node(10);
        root.left = new Node(2);
        root.right = new Node(11);

        root.left.left = new Node(1);
        root.left.right = new Node(5);

        root.left.right.left = new Node(3);
        root.left.right.right = new Node(6);

        root.left.right.left.right = new Node(4);

        int k = 7;

        System.out.println(kthLargest(root, k));
    }
}
Python
class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

# Function which will traverse the BST
# in reverse inorder manner.


def kthLargestRecur(root, cnt, k):

    # base case
    if not root:
        return -1

    right = kthLargestRecur(root.right, cnt, k)

    # if kth largest number is present in
    # right subtree, then return it.
    if right != -1:
        return right

    # Increment the node count.
    cnt[0] += 1

    # If root node is the kth largest element,
    # then return it.
    if cnt[0] == k:
        return root.data

    left = kthLargestRecur(root.left, cnt, k)

    # else return value provided by
    # left subtree.
    return left


def kthLargest(root, k):
    cnt = [0]
    return kthLargestRecur(root, cnt, k)


if __name__ == '__main__':
    # Create the following BST:
    #
    #          10
    #         /  \
    #        2    11
    #       / \
    #      1   5
    #         / \
    #        3   6
    #         \
    #          4
    #
    root = Node(10)
    root.left = Node(2)
    root.right = Node(11)

    root.left.left = Node(1)
    root.left.right = Node(5)

    root.left.right.left = Node(3)
    root.left.right.right = Node(6)

    root.left.right.left.right = Node(4)

    k = 7

    print(kthLargest(root, k))
C#
using System;

class Node {
    public int data;
    public Node left;
    public Node right;

    public Node(int x)
    {
        data = x;
        left = right = null;
    }
}

class GFG {
    // Function which will traverse the BST
    // in reverse inorder manner.
    static int kthLargestRecur(Node root, ref int cnt,
                               int k)
    {
        // Base case
        if (root == null)
            return -1;

        int right = kthLargestRecur(root.right, ref cnt, k);

        // If kth largest number is present in
        // right subtree, then return it.
        if (right != -1)
            return right;

        // Increment the node count.
        cnt++;

        // If root node is the kth largest element,
        // then return it.
        if (cnt == k)
            return root.data;

        int left = kthLargestRecur(root.left, ref cnt, k);

        // Else return value provided by
        // left subtree.
        return left;
    }

    static int kthLargest(Node root, int k)
    {
        int cnt = 0;
        return kthLargestRecur(root, ref cnt, k);
    }

    static void Main()
    {
        // Create the following BST:
        //
        //          10
        //         /  \
        //        2    11
        //       / \
        //      1   5
        //         / \
        //        3   6
        //         \
        //          4
        //

        Node root = new Node(10);
        root.left = new Node(2);
        root.right = new Node(11);

        root.left.left = new Node(1);
        root.left.right = new Node(5);

        root.left.right.left = new Node(3);
        root.left.right.right = new Node(6);

        root.left.right.left.right = new Node(4);

        int k = 7;

        Console.WriteLine(kthLargest(root, k));
    }
}
JavaScript
class Node {
    constructor(data)
    {
        this.data = data;
        this.left = null;
        this.right = null;
    }
}

// Function which will traverse the BST
// in reverse inorder manner.
function kthLargestRecur(root, cnt, k)
{

    // base case
    if (!root)
        return -1;

    let right = kthLargestRecur(root.right, cnt, k);

    // if kth largest number is present in
    // right subtree, then return it.
    if (right != -1)
        return right;

    // Increment the node count.
    cnt[0]++;

    // If root node is the kth largest element,
    // then return it.
    if (cnt[0] == k)
        return root.data;

    let left = kthLargestRecur(root.left, cnt, k);

    // else return value provided by
    // left subtree.
    return left;
}

function kthLargest(root, k)
{
    let cnt = [ 0 ];
    return kthLargestRecur(root, cnt, k);
}

// Driver code
// Create the following BST:
//          10
//         /  \
//        2    11
//       / \
//      1   5
//         / \
//        3   6
//         \
//          4
let root = new Node(10);
root.left = new Node(2);
root.right = new Node(11);

root.left.left = new Node(1);
root.left.right = new Node(5);

root.left.right.left = new Node(3);
root.left.right.right = new Node(6);

root.left.right.left.right = new Node(4);

let k = 7;

console.log(kthLargest(root, k));

Output
2

Using Morris Traversal Algorithm - O(n) Time and O(1) Space

The idea is to use Reverse Morris Traversal Algorithm to traverse the binary search tree in reverse in-order manner and maintain the count of nodes traversed so far. If number of nodes traversed become equal to k, then return the node.

Working of Approach:

  • Traverse the BST in reverse inorder (Right -> Root -> Left) using Reverse Morris Traversal.
  • For every node having a right child, create a temporary thread from the leftmost node of its right subtree back to the current node.
  • When the thread is encountered again, remove it, visit the current node, and increment the count of visited nodes.
  • If the count becomes equal to k, the current node is the k-th largest element and its value is returned.
  • Since only temporary threads are used, the traversal requires O(1) auxiliary space and restores the original BST structure before finishing.
C++
#include <iostream>
using namespace std;

class Node
{
  public:
    int data;
    Node *left;
    Node *right;

    Node(int val)
    {
        data = val;
        left = right = nullptr;
    }
};

int kthLargest(Node *root, int k)
{
    Node *curr = root;
    int cnt = 0;

    // Traverse the BST in reverse inorder
    while (curr)
    {
        // If there is no right child, visit the current node
        if (curr->right == nullptr)
        {
            cnt++;

            // If current node is the kth largest, return its value
            if (cnt == k)
                return curr->data;

            // Move to the left subtree
            curr = curr->left;
        }
        else
        {
            // Find the inorder successor of the current node
            Node *succ = curr->right;
            while (succ->left && succ->left != curr)
                succ = succ->left;

            // Create a temporary thread to the current node
            if (succ->left == nullptr)
            {
                succ->left = curr;
                curr = curr->right;
            }
            else
            {
                // Remove the temporary thread
                succ->left = nullptr;

                // Visit the current node
                cnt++;

                // If current node is the kth largest, return its value
                if (cnt == k)
                    return curr->data;

                // Move to the left subtree
                curr = curr->left;
            }
        }
    }

    // Return -1 if k is greater than the number of nodes
    return -1;
}

int main()
{
    // Create the following BST:
    //
    //          10
    //         /  \
    //        2    11
    //       / \
    //      1   5
    //         / \
    //        3   6
    //         \
    //          4
    //

    Node *root = new Node(10);
    root->left = new Node(2);
    root->right = new Node(11);

    root->left->left = new Node(1);
    root->left->right = new Node(5);

    root->left->right->left = new Node(3);
    root->left->right->right = new Node(6);

    root->left->right->left->right = new Node(4);

    int k = 7;

    cout << kthLargest(root, k);

    return 0;
}
Java
import java.util.*;

class Node {
    int data;
    Node left, right;

    Node(int val)
    {
        data = val;
        left = right = null;
    }
}

public class GFG {
    // Function to find kth largest element in BST
    static int kthLargest(Node root, int k)
    {
        Node curr = root;
        int cnt = 0;

        // Traverse the BST in reverse inorder
        while (curr != null) {
            // If there is no right child, visit the current
            // node
            if (curr.right == null) {
                cnt++;

                // If current node is the kth largest,
                // return its value
                if (cnt == k)
                    return curr.data;

                // Move to the left subtree
                curr = curr.left;
            }
            else {
                // Find the inorder successor of the current
                // node
                Node succ = curr.right;
                while (succ.left != null
                       && succ.left != curr)
                    succ = succ.left;

                // Create a temporary thread to the current
                // node
                if (succ.left == null) {
                    succ.left = curr;
                    curr = curr.right;
                }
                else {
                    // Remove the temporary thread
                    succ.left = null;

                    // Visit the current node
                    cnt++;

                    // If current node is the kth largest,
                    // return its value
                    if (cnt == k)
                        return curr.data;

                    // Move to the left subtree
                    curr = curr.left;
                }
            }
        }

        // Return -1 if k is greater than the number of
        // nodes
        return -1;
    }

    public static void main(String[] args)
    {
        // Create the following BST:
        //
        //          10
        //         /  \
        //        2    11
        //       / \
        //      1   5
        //         / \
        //        3   6
        //         \
        //          4
        //

        Node root = new Node(10);
        root.left = new Node(2);
        root.right = new Node(11);

        root.left.left = new Node(1);
        root.left.right = new Node(5);

        root.left.right.left = new Node(3);
        root.left.right.right = new Node(6);

        root.left.right.left.right = new Node(4);

        int k = 7;

        System.out.println(kthLargest(root, k));
    }
}
Python
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None


def kthLargest(root, k):
    curr = root
    cnt = 0

    # Traverse the BST in reverse inorder
    while curr:
        # If there is no right child, visit the current node
        if curr.right is None:
            cnt += 1

            # If current node is the kth largest, return its value
            if cnt == k:
                return curr.data

            # Move to the left subtree
            curr = curr.left
        else:
            # Find the inorder successor of the current node
            succ = curr.right
            while succ.left and succ.left != curr:
                succ = succ.left

            # Create a temporary thread to the current node
            if succ.left is None:
                succ.left = curr
                curr = curr.right
            else:
                # Remove the temporary thread
                succ.left = None

                # Visit the current node
                cnt += 1

                # If current node is the kth largest, return its value
                if cnt == k:
                    return curr.data

                # Move to the left subtree
                curr = curr.left

    # Return -1 if k is greater than the number of nodes
    return -1


if __name__ == '__main__':
    # Create the following BST:
    #
    #          10
    #         /  \
    #        2    11
    #       / \
    #      1   5
    #         / \
    #        3   6
    #         \
    #          4
    #

    root = Node(10)
    root.left = Node(2)
    root.right = Node(11)

    root.left.left = Node(1)
    root.left.right = Node(5)

    root.left.right.left = Node(3)
    root.left.right.right = Node(6)

    root.left.right.left.right = Node(4)

    k = 7

    print(kthLargest(root, k))
C#
using System;

public class Node {
    public int data;
    public Node left;
    public Node right;

    public Node(int val)
    {
        data = val;
        left = right = null;
    }
}

public class GFG {
    public static int kthLargest(Node root, int k)
    {
        Node curr = root;
        int cnt = 0;

        // Traverse the BST in reverse inorder
        while (curr != null) {
            // If there is no right child, visit the current
            // node
            if (curr.right == null) {
                cnt++;

                // If current node is the kth largest,
                // return its value
                if (cnt == k)
                    return curr.data;

                // Move to the left subtree
                curr = curr.left;
            }
            else {
                // Find the inorder successor of the current
                // node
                Node succ = curr.right;
                while (succ.left != null
                       && succ.left != curr)
                    succ = succ.left;

                // Create a temporary thread to the current
                // node
                if (succ.left == null) {
                    succ.left = curr;
                    curr = curr.right;
                }
                else {
                    // Remove the temporary thread
                    succ.left = null;

                    // Visit the current node
                    cnt++;

                    // If current node is the kth largest,
                    // return its value
                    if (cnt == k)
                        return curr.data;

                    // Move to the left subtree
                    curr = curr.left;
                }
            }
        }

        // Return -1 if k is greater than the number of
        // nodes
        return -1;
    }

    public static void Main()
    {
        // Create the following BST:
        //
        //          10
        //         /  \
        //        2    11
        //       / \
        //      1   5
        //         / \
        //        3   6
        //         \
        //          4

        Node root = new Node(10);
        root.left = new Node(2);
        root.right = new Node(11);

        root.left.left = new Node(1);
        root.left.right = new Node(5);

        root.left.right.left = new Node(3);
        root.left.right.right = new Node(6);

        root.left.right.left.right = new Node(4);

        int k = 7;

        Console.WriteLine(kthLargest(root, k));
    }
}
JavaScript
class Node {
    constructor(val)
    {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}

function kthLargest(root, k)
{
    let curr = root;
    let cnt = 0;

    // Traverse the BST in reverse inorder
    while (curr) {
        // If there is no right child, visit the current
        // node
        if (curr.right === null) {
            cnt++;

            // If current node is the kth largest, return
            // its value
            if (cnt === k)
                return curr.data;

            // Move to the left subtree
            curr = curr.left;
        }
        else {
            // Find the inorder successor of the current
            // node
            let succ = curr.right;
            while (succ.left && succ.left !== curr)
                succ = succ.left;

            // Create a temporary thread to the current node
            if (succ.left === null) {
                succ.left = curr;
                curr = curr.right;
            }
            else {
                // Remove the temporary thread
                succ.left = null;

                // Visit the current node
                cnt++;

                // If current node is the kth largest,
                // return its value
                if (cnt === k)
                    return curr.data;

                // Move to the left subtree
                curr = curr.left;
            }
        }
    }

    // Return -1 if k is greater than the number of nodes
    return -1;
}

// Driver Code
// Create the following BST:
//
//          10
//         /  \
//        2    11
//       / \
//      1   5
//         / \
//        3   6
//         \
//          4
let root = new Node(10);
root.left = new Node(2);
root.right = new Node(11);

root.left.left = new Node(1);
root.left.right = new Node(5);

root.left.right.left = new Node(3);
root.left.right.right = new Node(6);

root.left.right.left.right = new Node(4);

let k = 7;

console.log(kthLargest(root, k));

Output
2
Comment