K'th Largest element in BST using constant extra space (original) (raw)
Last Updated : 11 Jul, 2025
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.
**Approach:
The idea is to use Reverse Morris Traversal which is based on Threaded Binary Trees. Threaded binary trees use the **NULL pointers to store the **successor and **predecessor information which helps us to utilize the wasted memory by those NULL pointers.
The special thing about Morris traversal is that we can do Inorder traversal without using **stack or **recursion which saves us memory consumed by stack or recursion call stack. Reverse Morris traversal is just the **reverse _of Morris traversal _which is majorly used to do Reverse Inorder traversal with **constant O(1) extra memory consumed as it does not uses any Stack or Recursion.
To find Kth largest element in a Binary search tree, the simplest logic is to do **reverse inorder traversal and while doing reverse inorder traversal simply keep a **count of number of Nodes visited. When the count becomes equal to **k, we stop the traversal and **print the data. It uses the fact that **reverse inorder traversal will give us a list sorted in descending order.
Below is the implementation of the above approach:
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 to perform Morris Traversal and // return kth largest element int kthLargest(Node* root, int k) {
// return -1 if root is null
if (root == nullptr) return -1;
Node* curr = root;
int cnt = 0;
while (curr != nullptr) {
// if right tree does not exists,
// then increment the count, check
// count==k. Otherwise,
// set curr = curr->left
if (curr->right == nullptr) {
cnt++;
// return current Node
// if cnt == k.
if (cnt == k)
return curr->data;
curr = curr->left;
}
else {
Node* succ = curr->right;
// find the inorder successor
while (succ->left != nullptr &&
succ->left != curr) {
succ = succ->left;
}
// create a linkage between succ and
// curr
if (succ->left == nullptr) {
succ->left = curr;
curr = curr->right;
}
// if succ->left = curr, it means
// we have processed the right subtree,
// and we can process curr node
else {
cnt++;
// remove the link
succ->left = nullptr;
// return current Node
// if cnt == k.
if (cnt == 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;}
C
// C Program to find kth largest element #include <stdio.h> #include <stdlib.h>
struct Node { int data; struct Node* left; struct Node* right; };
// Function to perform Morris Traversal and // return kth largest element int kthLargest(struct Node* root, int k) {
// return -1 if root is null
if (root == NULL) return -1;
struct Node* curr = root;
int cnt = 0;
while (curr != NULL) {
// if right tree does not exist,
// then increment the count, check
// count == k. Otherwise,
// set curr = curr->left
if (curr->right == NULL) {
cnt++;
// return current Node
// if cnt == k.
if (cnt == k)
return curr->data;
curr = curr->left;
} else {
struct Node* succ = curr->right;
// find the inorder successor
while (succ->left != NULL && succ->left != curr) {
succ = succ->left;
}
// create a linkage between pred and curr
if (succ->left == NULL) {
succ->left = curr;
curr = curr->right;
}
// if succ->left = curr, it means
// we have processed the right subtree,
// and we can process curr node
else {
cnt++;
// remove the link
succ->left = NULL;
// return current Node
// if cnt == k.
if (cnt == k)
return curr->data;
curr = curr->left;
}
}
}
return -1;}
struct Node* createNode(int x) { struct Node* node = (struct Node*)malloc(sizeof(struct Node)); node->data = x; node->left = NULL; node->right = NULL; return node; }
int main() {
// Create a hard-coded tree:
// 20
// / \
// 8 22
// / \
// 4 12
// / \
// 10 14
struct Node* root = createNode(20);
root->left = createNode(8);
root->right = createNode(22);
root->left->left = createNode(4);
root->left->right = createNode(12);
root->left->right->left = createNode(10);
root->left->right->right = createNode(14);
int k = 3;
printf("%d\n", kthLargest(root, k));
return 0;}
Java
// Java Program to find kth largest element class Node { int data; Node left, right;
Node(int x) {
data = x;
left = right = null;
}}
class GfG {
// Function to perform Morris Traversal
// and return kth largest element
static int kthLargest(Node root, int k) {
// return -1 if root is null
if (root == null) return -1;
Node curr = root;
int cnt = 0;
while (curr != null) {
// if right tree does not exist,
// then increment the count, check
// count == k. Otherwise,
// set curr = curr.left
if (curr.right == null) {
cnt++;
// return current Node
// if cnt == k.
if (cnt == k) return curr.data;
curr = curr.left;
} else {
Node succ = curr.right;
// find the inorder successor
while (succ.left != null &&
succ.left != curr) {
succ = succ.left;
}
// create a linkage between succ and curr
if (succ.left == null) {
succ.left = curr;
curr = curr.right;
} else {
cnt++;
// remove the link
succ.left = null;
// return current Node
// if cnt == k.
if (cnt == 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
class Node: def init(self, data): self.data = data self.left = None self.right = None
Function to perform Morris Traversal
and return kth largest element
def kth_largest(root, k):
# return -1 if root is null
if root is None:
return -1
curr = root
cnt = 0
while curr is not None:
# if right tree does not exist,
# then increment the count, check
# count == k. Otherwise,
# set curr = curr.left
if curr.right is None:
cnt += 1
# return current Node if cnt == k.
if cnt == k:
return curr.data
curr = curr.left
else:
succ = curr.right
# find the inorder successor
while succ.left is not None and succ.left != curr:
succ = succ.left
# create a linkage between succ and curr
if succ.left is None:
succ.left = curr
curr = curr.right
else:
cnt += 1
# remove the link
succ.left = None
# return current Node if cnt == k.
if cnt == k:
return curr.data
curr = curr.left
return -1if 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 System;
class Node { public int data; public Node left, right;
public Node(int x) {
data = x;
left = right = null;
}}
class GfG {
// Function to perform Morris Traversal and
// return kth largest element
static int KthLargest(Node root, int k) {
// return -1 if root is null
if (root == null) return -1;
Node curr = root;
int cnt = 0;
while (curr != null) {
// if right tree does not exist,
// then increment the count, check
// count == k. Otherwise,
// set curr = curr.left
if (curr.right == null) {
cnt++;
// return current Node
// if cnt == k
if (cnt == k)
return curr.data;
curr = curr.left;
} else {
Node succ = curr.right;
// find the inorder successor
while (succ.left != null && succ.left != curr) {
succ = succ.left;
}
// create a linkage between succ and curr
if (succ.left == null) {
succ.left = curr;
curr = curr.right;
}
// if succ.left == curr, it means
// we have processed the right subtree,
// and we can process curr node
else {
cnt++;
// remove the link
succ.left = null;
// return current Node
// if cnt == k
if (cnt == 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 class Node { constructor(data) { this.data = data; this.left = null; this.right = null; } }
// Function to perform Morris Traversal and // return kth largest element function kthLargest(root, k) {
// return -1 if root is null
if (root === null) return -1;
let curr = root;
let cnt = 0;
while (curr !== null) {
// if right tree does not exist,
// then increment the count, check
// count == k. Otherwise,
// set curr = curr.left
if (curr.right === null) {
cnt++;
// return current Node
// if cnt == k
if (cnt === k)
return curr.data;
curr = curr.left;
} else {
let succ = curr.right;
// find the inorder successor
while (succ.left !== null && succ.left !== curr) {
succ = succ.left;
}
// create a linkage between pred and curr
if (succ.left === null) {
succ.left = curr;
curr = curr.right;
}
// if succ.left == curr, it means
// we have processed the right subtree,
// and we can process curr node
else {
cnt++;
// remove the link
succ.left = null;
// return current Node
// if cnt == k
if (cnt === 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));
`
**Time Complexity: O(n), where n is the number of nodes in Binary tree.
**Auxiliary Space: O(1)
