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>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=right=nullptr;}};// Function which will traverse the BST// in reverse inorder manner.intkthLargestRecur(Node*root,int&cnt,intk){// base caseif(root==nullptr)return-1;intright=kthLargestRecur(root->right,cnt,k);// if kth largest number is present in// right subtree, then return it.if(right!=-1)returnright;// Increment the node count.cnt++;// If root node is the kth largest element,// then return it.if(cnt==k)returnroot->data;intleft=kthLargestRecur(root->left,cnt,k);// else return value provided by// left subtree.returnleft;}intkthLargest(Node*root,intk){intcnt=0;returnkthLargestRecur(root,cnt,k);}intmain(){// Create the following BST://// 10// / \ // 2 11// / \ // 1 5// / \ // 3 6// \ // 4//Node*root=newNode(10);root->left=newNode(2);root->right=newNode(11);root->left->left=newNode(1);root->left->right=newNode(5);root->left->right->left=newNode(3);root->left->right->right=newNode(6);root->left->right->left->right=newNode(4);intk=7;cout<<kthLargest(root,k);return0;}
Java
classNode{intdata;Nodeleft;Noderight;Node(intx){data=x;left=right=null;}}classGFG{// Function which will traverse the BST// in reverse inorder manner.staticintkthLargestRecur(Noderoot,int[]cnt,intk){// Base caseif(root==null)return-1;intright=kthLargestRecur(root.right,cnt,k);// If kth largest number is present in// right subtree, then return it.if(right!=-1)returnright;// Increment the node count.cnt[0]++;// If root node is the kth largest element,// then return it.if(cnt[0]==k)returnroot.data;intleft=kthLargestRecur(root.left,cnt,k);// Else return value provided by// left subtree.returnleft;}staticintkthLargest(Noderoot,intk){int[]cnt={0};returnkthLargestRecur(root,cnt,k);}publicstaticvoidmain(String[]args){// Create the following BST://// 10// / \// 2 11// / \// 1 5// / \// 3 6// \// 4//Noderoot=newNode(10);root.left=newNode(2);root.right=newNode(11);root.left.left=newNode(1);root.left.right=newNode(5);root.left.right.left=newNode(3);root.left.right.right=newNode(6);root.left.right.left.right=newNode(4);intk=7;System.out.println(kthLargest(root,k));}}
Python
classNode:def__init__(self,data):self.data=dataself.left=Noneself.right=None# Function which will traverse the BST# in reverse inorder manner.defkthLargestRecur(root,cnt,k):# base caseifnotroot:return-1right=kthLargestRecur(root.right,cnt,k)# if kth largest number is present in# right subtree, then return it.ifright!=-1:returnright# Increment the node count.cnt[0]+=1# If root node is the kth largest element,# then return it.ifcnt[0]==k:returnroot.dataleft=kthLargestRecur(root.left,cnt,k)# else return value provided by# left subtree.returnleftdefkthLargest(root,k):cnt=[0]returnkthLargestRecur(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=7print(kthLargest(root,k))
C#
usingSystem;classNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intx){data=x;left=right=null;}}classGFG{// Function which will traverse the BST// in reverse inorder manner.staticintkthLargestRecur(Noderoot,refintcnt,intk){// Base caseif(root==null)return-1;intright=kthLargestRecur(root.right,refcnt,k);// If kth largest number is present in// right subtree, then return it.if(right!=-1)returnright;// Increment the node count.cnt++;// If root node is the kth largest element,// then return it.if(cnt==k)returnroot.data;intleft=kthLargestRecur(root.left,refcnt,k);// Else return value provided by// left subtree.returnleft;}staticintkthLargest(Noderoot,intk){intcnt=0;returnkthLargestRecur(root,refcnt,k);}staticvoidMain(){// Create the following BST://// 10// / \// 2 11// / \// 1 5// / \// 3 6// \// 4//Noderoot=newNode(10);root.left=newNode(2);root.right=newNode(11);root.left.left=newNode(1);root.left.right=newNode(5);root.left.right.left=newNode(3);root.left.right.right=newNode(6);root.left.right.left.right=newNode(4);intk=7;Console.WriteLine(kthLargest(root,k));}}
JavaScript
classNode{constructor(data){this.data=data;this.left=null;this.right=null;}}// Function which will traverse the BST// in reverse inorder manner.functionkthLargestRecur(root,cnt,k){// base caseif(!root)return-1;letright=kthLargestRecur(root.right,cnt,k);// if kth largest number is present in// right subtree, then return it.if(right!=-1)returnright;// Increment the node count.cnt[0]++;// If root node is the kth largest element,// then return it.if(cnt[0]==k)returnroot.data;letleft=kthLargestRecur(root.left,cnt,k);// else return value provided by// left subtree.returnleft;}functionkthLargest(root,k){letcnt=[0];returnkthLargestRecur(root,cnt,k);}// Driver code// Create the following BST:// 10// / \// 2 11// / \// 1 5// / \// 3 6// \// 4letroot=newNode(10);root.left=newNode(2);root.right=newNode(11);root.left.left=newNode(1);root.left.right=newNode(5);root.left.right.left=newNode(3);root.left.right.right=newNode(6);root.left.right.left.right=newNode(4);letk=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>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=right=nullptr;}};intkthLargest(Node*root,intk){Node*curr=root;intcnt=0;// Traverse the BST in reverse inorderwhile(curr){// If there is no right child, visit the current nodeif(curr->right==nullptr){cnt++;// If current node is the kth largest, return its valueif(cnt==k)returncurr->data;// Move to the left subtreecurr=curr->left;}else{// Find the inorder successor of the current nodeNode*succ=curr->right;while(succ->left&&succ->left!=curr)succ=succ->left;// Create a temporary thread to the current nodeif(succ->left==nullptr){succ->left=curr;curr=curr->right;}else{// Remove the temporary threadsucc->left=nullptr;// Visit the current nodecnt++;// If current node is the kth largest, return its valueif(cnt==k)returncurr->data;// Move to the left subtreecurr=curr->left;}}}// Return -1 if k is greater than the number of nodesreturn-1;}intmain(){// Create the following BST://// 10// / \ // 2 11// / \ // 1 5// / \ // 3 6// \ // 4//Node*root=newNode(10);root->left=newNode(2);root->right=newNode(11);root->left->left=newNode(1);root->left->right=newNode(5);root->left->right->left=newNode(3);root->left->right->right=newNode(6);root->left->right->left->right=newNode(4);intk=7;cout<<kthLargest(root,k);return0;}
Java
importjava.util.*;classNode{intdata;Nodeleft,right;Node(intval){data=val;left=right=null;}}publicclassGFG{// Function to find kth largest element in BSTstaticintkthLargest(Noderoot,intk){Nodecurr=root;intcnt=0;// Traverse the BST in reverse inorderwhile(curr!=null){// If there is no right child, visit the current// nodeif(curr.right==null){cnt++;// If current node is the kth largest,// return its valueif(cnt==k)returncurr.data;// Move to the left subtreecurr=curr.left;}else{// Find the inorder successor of the current// nodeNodesucc=curr.right;while(succ.left!=null&&succ.left!=curr)succ=succ.left;// Create a temporary thread to the current// nodeif(succ.left==null){succ.left=curr;curr=curr.right;}else{// Remove the temporary threadsucc.left=null;// Visit the current nodecnt++;// If current node is the kth largest,// return its valueif(cnt==k)returncurr.data;// Move to the left subtreecurr=curr.left;}}}// Return -1 if k is greater than the number of// nodesreturn-1;}publicstaticvoidmain(String[]args){// Create the following BST://// 10// / \// 2 11// / \// 1 5// / \// 3 6// \// 4//Noderoot=newNode(10);root.left=newNode(2);root.right=newNode(11);root.left.left=newNode(1);root.left.right=newNode(5);root.left.right.left=newNode(3);root.left.right.right=newNode(6);root.left.right.left.right=newNode(4);intk=7;System.out.println(kthLargest(root,k));}}
Python
classNode:def__init__(self,val):self.data=valself.left=Noneself.right=NonedefkthLargest(root,k):curr=rootcnt=0# Traverse the BST in reverse inorderwhilecurr:# If there is no right child, visit the current nodeifcurr.rightisNone:cnt+=1# If current node is the kth largest, return its valueifcnt==k:returncurr.data# Move to the left subtreecurr=curr.leftelse:# Find the inorder successor of the current nodesucc=curr.rightwhilesucc.leftandsucc.left!=curr:succ=succ.left# Create a temporary thread to the current nodeifsucc.leftisNone:succ.left=currcurr=curr.rightelse:# Remove the temporary threadsucc.left=None# Visit the current nodecnt+=1# If current node is the kth largest, return its valueifcnt==k:returncurr.data# Move to the left subtreecurr=curr.left# Return -1 if k is greater than the number of nodesreturn-1if__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=7print(kthLargest(root,k))
C#
usingSystem;publicclassNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intval){data=val;left=right=null;}}publicclassGFG{publicstaticintkthLargest(Noderoot,intk){Nodecurr=root;intcnt=0;// Traverse the BST in reverse inorderwhile(curr!=null){// If there is no right child, visit the current// nodeif(curr.right==null){cnt++;// If current node is the kth largest,// return its valueif(cnt==k)returncurr.data;// Move to the left subtreecurr=curr.left;}else{// Find the inorder successor of the current// nodeNodesucc=curr.right;while(succ.left!=null&&succ.left!=curr)succ=succ.left;// Create a temporary thread to the current// nodeif(succ.left==null){succ.left=curr;curr=curr.right;}else{// Remove the temporary threadsucc.left=null;// Visit the current nodecnt++;// If current node is the kth largest,// return its valueif(cnt==k)returncurr.data;// Move to the left subtreecurr=curr.left;}}}// Return -1 if k is greater than the number of// nodesreturn-1;}publicstaticvoidMain(){// Create the following BST://// 10// / \// 2 11// / \// 1 5// / \// 3 6// \// 4Noderoot=newNode(10);root.left=newNode(2);root.right=newNode(11);root.left.left=newNode(1);root.left.right=newNode(5);root.left.right.left=newNode(3);root.left.right.right=newNode(6);root.left.right.left.right=newNode(4);intk=7;Console.WriteLine(kthLargest(root,k));}}
JavaScript
classNode{constructor(val){this.data=val;this.left=null;this.right=null;}}functionkthLargest(root,k){letcurr=root;letcnt=0;// Traverse the BST in reverse inorderwhile(curr){// If there is no right child, visit the current// nodeif(curr.right===null){cnt++;// If current node is the kth largest, return// its valueif(cnt===k)returncurr.data;// Move to the left subtreecurr=curr.left;}else{// Find the inorder successor of the current// nodeletsucc=curr.right;while(succ.left&&succ.left!==curr)succ=succ.left;// Create a temporary thread to the current nodeif(succ.left===null){succ.left=curr;curr=curr.right;}else{// Remove the temporary threadsucc.left=null;// Visit the current nodecnt++;// If current node is the kth largest,// return its valueif(cnt===k)returncurr.data;// Move to the left subtreecurr=curr.left;}}}// Return -1 if k is greater than the number of nodesreturn-1;}// Driver Code// Create the following BST://// 10// / \// 2 11// / \// 1 5// / \// 3 6// \// 4letroot=newNode(10);root.left=newNode(2);root.right=newNode(11);root.left.left=newNode(1);root.left.right=newNode(5);root.left.right.left=newNode(3);root.left.right.right=newNode(6);root.left.right.left.right=newNode(4);letk=7;console.log(kthLargest(root,k));