K'th Largest Element in BST when modification to BST is not allowed
Last Updated :
28 Oct, 2024
Given a Binary Search Tree (BST) and a positive integer k, the task is to find the kth largest element in the Binary Search Tree.
Example:
Input: k = 3

Output: 14
Explanation: If we sort the BST in decreasing order, then it will become 22, 20, 14, 12, 10, 8, 4. 14 is the 3rd largest element.
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.
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 = nullptr;
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 a hard coded tree.
// 20
// / \
// 8 22
// / \
// 4 12
// / \
// 10 14
Node* root = new Node(20);
root->left = new Node(8);
root->right = new Node(22);
root->left->left = new Node(4);
root->left->right = new Node(12);
root->left->right->left = new Node(10);
root->left->right->right = new Node(14);
int k = 3;
cout << kthLargest(root, k) << endl;
return 0;
}
Java
//Java Program to find kth largest element
import java.util.*;
class Node {
int data;
Node left, right;
Node(int x) {
data = x;
left = null;
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;
// Traverse the right subtree first
// (larger elements)
int right = kthLargestRecur(root.right, cnt, k);
// If kth largest number is present in right
// subtree, return it.
if (right != -1)
return right;
// Increment the node count.
cnt[0]++;
// If root node is the kth largest element,
// return it.
if (cnt[0] == k)
return root.data;
// Otherwise, traverse the left subtree.
return kthLargestRecur(root.left, cnt, k);
}
static int kthLargest(Node root, int k) {
int[] cnt = new int[1];
return kthLargestRecur(root, cnt, k);
}
public static void main(String[] args) {
// Create a hard coded tree.
// 20
// / \
// 8 22
// / \
// 4 12
// / \
// 10 14
Node root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(4);
root.left.right = new Node(12);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);
int k = 3;
System.out.println(kthLargest(root, k));
}
}
Python
# Python Program to find kth largest element
class Node:
def __init__(self, x):
self.data = x
self.left = None
self.right = None
def kthLargest(root, k):
# Use a list to maintain the
# count as reference
count = [0]
def kthLargestRecur(node):
if node is None:
return -1
# Traverse the right subtree
# first (larger elements)
right = kthLargestRecur(node.right)
if right != -1:
return right
# Increment the node count
count[0] += 1
if count[0] == k:
return node.data
# Traverse the left subtree
return kthLargestRecur(node.left)
return kthLargestRecur(root)
if __name__ == "__main__":
# Create a hard coded tree.
# 20
# / \
# 8 22
# / \
# 4 12
# / \
# 10 14
root = Node(20)
root.left = Node(8)
root.right = Node(22)
root.left.left = Node(4)
root.left.right = Node(12)
root.left.right.left = Node(10)
root.left.right.right = Node(14)
k = 3
print(kthLargest(root, k))
C#
// C# Program to find kth largest element
using System;
class Node {
public int data;
public Node left, 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(string[] args) {
// Create a hard coded tree.
// 20
// / \
// 8 22
// / \
// 4 12
// / \
// 10 14
Node root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(4);
root.left.right = new Node(12);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);
int k = 3;
Console.WriteLine(KthLargest(root, k));
}
}
JavaScript
// Javascript Program to find kth largest element
class Node {
constructor(x) {
this.data = x;
this.left = null;
this.right = null;
}
}
// Function which will traverse the BST in
// reverse in-order manner
function kthLargestRecur(node, count, k) {
// Base case
if (node === null) {
return -1;
}
// Traverse the right subtree first (larger elements)
let right = kthLargestRecur(node.right, count, k);
if (right !== -1) {
// If the k-th largest number
// is found in the right subtree
return right;
}
count.value++;
// If root node is the k-th largest
// element, return it
if (count.value === k) {
return node.data;
}
// Otherwise, traverse the left subtree
return kthLargestRecur(node.left, count, k);
}
function kthLargest(root, k) {
// Use an object to maintain count
// as reference
const count = { value: 0 };
return kthLargestRecur(root, count, k);
}
// Create a hard-coded tree.
// 20
// / \
// 8 22
// / \
// 4 12
// / \
// 10 14
let root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(4);
root.left.right = new Node(12);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);
let k = 3;
console.log(kthLargest(root, k));
Using Stack - O(n) Time and O(h) Space
The idea is to similar to recursion, but in this method, stack will be used 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.
Below is the implementation of the above approach:
C++
// C++ Program to find kth largest element
// using stack
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node* left;
Node* right;
Node (int x) {
data = x;
left = nullptr;
right = nullptr;
}
};
int kthLargest(Node* root, int k) {
stack<Node*> st;
Node* curr = root;
int count = 0;
while (curr != nullptr || !st.empty()) {
// Push the right child child
// nodes into stack
while (curr != nullptr) {
st.push(curr);
curr = curr->right;
}
curr = st.top();
st.pop();
// increment the count
count++;
// return curr node
// if count == k
if (count == k) {
return curr->data;
}
curr = curr->left;
}
return -1;
}
int main() {
// Create a hard coded tree.
// 20
// / \
// 8 22
// / \
// 4 12
// / \
// 10 14
Node* root = new Node(20);
root->left = new Node(8);
root->right = new Node(22);
root->left->left = new Node(4);
root->left->right = new Node(12);
root->left->right->left = new Node(10);
root->left->right->right = new Node(14);
int k = 3;
cout << kthLargest(root, k) << endl;
return 0;
}
Java
// Java Program to find kth largest element
// using stack
import java.util.Stack;
class Node {
int data;
Node left, right;
Node(int x) {
data = x;
left = right = null;
}
}
class GfG {
static int kthLargest(Node root, int k) {
Stack<Node> st = new Stack<>();
Node curr = root;
int count = 0;
while (curr != null || !st.isEmpty()) {
// Push the right child nodes
// into stack
while (curr != null) {
st.push(curr);
curr = curr.right;
}
curr = st.pop();
// increment the count
count++;
// return curr node if count == k
if (count == k) {
return curr.data;
}
curr = curr.left;
}
return -1;
}
public static void main(String[] args) {
// Create a hard-coded tree:
// 20
// / \
// 8 22
// / \
// 4 12
// / \
// 10 14
Node root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(4);
root.left.right = new Node(12);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);
int k = 3;
System.out.println(kthLargest(root, k));
}
}
Python
# Python Program to find kth largest element
# using stack
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
def kth_largest(root, k):
stack = []
curr = root
count = 0
while curr is not None or stack:
# Push the right child nodes
# into stack
while curr is not None:
stack.append(curr)
curr = curr.right
curr = stack.pop()
# increment the count
count += 1
# return curr node if
# count == k
if count == k:
return curr.data
curr = curr.left
return -1
if __name__ == "__main__":
# Create a hard-coded tree:
# 20
# / \
# 8 22
# / \
# 4 12
# / \
# 10 14
root = Node(20)
root.left = Node(8)
root.right = Node(22)
root.left.left = Node(4)
root.left.right = Node(12)
root.left.right.left = Node(10)
root.left.right.right = Node(14)
k = 3
print(kth_largest(root, k))
C#
// C# Program to find kth largest element
// using stack
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 {
static int KthLargest(Node root, int k) {
Stack<Node> st = new Stack<Node>();
Node curr = root;
int count = 0;
while (curr != null || st.Count > 0) {
// Push the right child nodes
// into stack
while (curr != null) {
st.Push(curr);
curr = curr.right;
}
curr = st.Pop();
// increment the count
count++;
// return curr node if
// count == k
if (count == k) {
return curr.data;
}
curr = curr.left;
}
return -1;
}
static void Main(string[] args) {
// Create a hard-coded tree:
// 20
// / \
// 8 22
// / \
// 4 12
// / \
// 10 14
Node root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(4);
root.left.right = new Node(12);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);
int k = 3;
Console.WriteLine(KthLargest(root, k));
}
}
JavaScript
// JavaScript Program to find kth largest element
// using stack
class Node {
constructor(data) {
this.data = data;
this.left = null;
this.right = null;
}
}
function kthLargest(root, k) {
let st = [];
let curr = root;
let count = 0;
while (curr !== null || st.length > 0) {
// Push the right child nodes
// into stack
while (curr !== null) {
st.push(curr);
curr = curr.right;
}
curr = st.pop();
// increment the count
count++;
// return curr node if
// count == k
if (count === k) {
return curr.data;
}
curr = curr.left;
}
return -1;
}
// Create a hard-coded tree:
// 20
// / \
// 8 22
// / \
// 4 12
// / \
// 10 14
let root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(4);
root.left.right = new Node(12);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);
let k = 3;
console.log(kthLargest(root, k));
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. Please refer to K’th Largest element in BST using constant extra space for implementation.
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