K'th Largest element in BST using constant extra space
Last Updated : 14 Oct, 2024
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report
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>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=nullptr;right=nullptr;}};// Function to perform Morris Traversal and // return kth largest elementintkthLargest(Node*root,intk){// return -1 if root is nullif(root==nullptr)return-1;Node*curr=root;intcnt=0;while(curr!=nullptr){// if right tree does not exists,// then increment the count, check // count==k. Otherwise, // set curr = curr->leftif(curr->right==nullptr){cnt++;// return current Node// if cnt == k.if(cnt==k)returncurr->data;curr=curr->left;}else{Node*succ=curr->right;// find the inorder successorwhile(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 nodeelse{cnt++;// remove the link succ->left=nullptr;// return current Node// if cnt == k.if(cnt==k)returncurr->data;curr=curr->left;}}}return-1;}intmain(){// Create a hard coded tree.// 20// / \ // 8 22// / \ // 4 12 // / \ // 10 14Node*root=newNode(20);root->left=newNode(8);root->right=newNode(22);root->left->left=newNode(4);root->left->right=newNode(12);root->left->right->left=newNode(10);root->left->right->right=newNode(14);intk=3;cout<<kthLargest(root,k)<<endl;return0;}
C
// C Program to find kth largest element#include<stdio.h>#include<stdlib.h>structNode{intdata;structNode*left;structNode*right;};// Function to perform Morris Traversal and // return kth largest elementintkthLargest(structNode*root,intk){// return -1 if root is nullif(root==NULL)return-1;structNode*curr=root;intcnt=0;while(curr!=NULL){// if right tree does not exist,// then increment the count, check // count == k. Otherwise, // set curr = curr->leftif(curr->right==NULL){cnt++;// return current Node// if cnt == k.if(cnt==k)returncurr->data;curr=curr->left;}else{structNode*succ=curr->right;// find the inorder successorwhile(succ->left!=NULL&&succ->left!=curr){succ=succ->left;}// create a linkage between pred and currif(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 nodeelse{cnt++;// remove the linksucc->left=NULL;// return current Node// if cnt == k.if(cnt==k)returncurr->data;curr=curr->left;}}}return-1;}structNode*createNode(intx){structNode*node=(structNode*)malloc(sizeof(structNode));node->data=x;node->left=NULL;node->right=NULL;returnnode;}intmain(){// Create a hard-coded tree:// 20// / \ // 8 22// / \ // 4 12// / \ // 10 14structNode*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);intk=3;printf("%d\n",kthLargest(root,k));return0;}
Java
// Java Program to find kth largest elementclassNode{intdata;Nodeleft,right;Node(intx){data=x;left=right=null;}}classGfG{// Function to perform Morris Traversal // and return kth largest elementstaticintkthLargest(Noderoot,intk){// return -1 if root is nullif(root==null)return-1;Nodecurr=root;intcnt=0;while(curr!=null){// if right tree does not exist,// then increment the count, check // count == k. Otherwise, // set curr = curr.leftif(curr.right==null){cnt++;// return current Node// if cnt == k.if(cnt==k)returncurr.data;curr=curr.left;}else{Nodesucc=curr.right;// find the inorder successorwhile(succ.left!=null&&succ.left!=curr){succ=succ.left;}// create a linkage between succ and currif(succ.left==null){succ.left=curr;curr=curr.right;}else{cnt++;// remove the linksucc.left=null;// return current Node// if cnt == k.if(cnt==k)returncurr.data;curr=curr.left;}}}return-1;}publicstaticvoidmain(String[]args){// Create a hard-coded tree:// 20// / \// 8 22// / \// 4 12// / \// 10 14Noderoot=newNode(20);root.left=newNode(8);root.right=newNode(22);root.left.left=newNode(4);root.left.right=newNode(12);root.left.right.left=newNode(10);root.left.right.right=newNode(14);intk=3;System.out.println(kthLargest(root,k));}}
Python
# Python Program to find kth largest elementclassNode:def__init__(self,data):self.data=dataself.left=Noneself.right=None# Function to perform Morris Traversal # and return kth largest elementdefkth_largest(root,k):# return -1 if root is nullifrootisNone:return-1curr=rootcnt=0whilecurrisnotNone:# if right tree does not exist,# then increment the count, check # count == k. Otherwise, # set curr = curr.leftifcurr.rightisNone:cnt+=1# return current Node if cnt == k.ifcnt==k:returncurr.datacurr=curr.leftelse:succ=curr.right# find the inorder successorwhilesucc.leftisnotNoneandsucc.left!=curr:succ=succ.left# create a linkage between succ and currifsucc.leftisNone:succ.left=currcurr=curr.rightelse:cnt+=1# remove the linksucc.left=None# return current Node if cnt == k.ifcnt==k:returncurr.datacurr=curr.leftreturn-1if__name__=="__main__":# Create a hard-coded tree:# 20# / \# 8 22# / \# 4 12# / \# 10 14root=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=3print(kth_largest(root,k))
C#
// C# Program to find kth largest elementusingSystem;classNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=right=null;}}classGfG{// Function to perform Morris Traversal and // return kth largest elementstaticintKthLargest(Noderoot,intk){// return -1 if root is nullif(root==null)return-1;Nodecurr=root;intcnt=0;while(curr!=null){// if right tree does not exist,// then increment the count, check // count == k. Otherwise, // set curr = curr.leftif(curr.right==null){cnt++;// return current Node// if cnt == kif(cnt==k)returncurr.data;curr=curr.left;}else{Nodesucc=curr.right;// find the inorder successorwhile(succ.left!=null&&succ.left!=curr){succ=succ.left;}// create a linkage between succ and currif(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 nodeelse{cnt++;// remove the link succ.left=null;// return current Node// if cnt == kif(cnt==k)returncurr.data;curr=curr.left;}}}return-1;}staticvoidMain(string[]args){// Create a hard-coded tree:// 20// / \// 8 22// / \// 4 12// / \// 10 14Noderoot=newNode(20);root.left=newNode(8);root.right=newNode(22);root.left.left=newNode(4);root.left.right=newNode(12);root.left.right.left=newNode(10);root.left.right.right=newNode(14);intk=3;Console.WriteLine(KthLargest(root,k));}}
JavaScript
// JavaScript Program to find kth largest elementclassNode{constructor(data){this.data=data;this.left=null;this.right=null;}}// Function to perform Morris Traversal and // return kth largest elementfunctionkthLargest(root,k){// return -1 if root is nullif(root===null)return-1;letcurr=root;letcnt=0;while(curr!==null){// if right tree does not exist,// then increment the count, check // count == k. Otherwise, // set curr = curr.leftif(curr.right===null){cnt++;// return current Node// if cnt == kif(cnt===k)returncurr.data;curr=curr.left;}else{letsucc=curr.right;// find the inorder successorwhile(succ.left!==null&&succ.left!==curr){succ=succ.left;}// create a linkage between pred and currif(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 nodeelse{cnt++;// remove the link succ.left=null;// return current Node// if cnt == kif(cnt===k)returncurr.data;curr=curr.left;}}}return-1;}// Create a hard-coded tree:// 20// / \// 8 22// / \// 4 12// / \// 10 14letroot=newNode(20);root.left=newNode(8);root.right=newNode(22);root.left.left=newNode(4);root.left.right=newNode(12);root.left.right.left=newNode(10);root.left.right.right=newNode(14);letk=3;console.log(kthLargest(root,k));
Output
14
Time Complexity: O(n), where n is the number of nodes in Binary tree. Auxiliary Space: O(1)
We use cookies to ensure you have the best browsing experience on our website. By using our site, you
acknowledge that you have read and understood our
Cookie Policy &
Privacy Policy
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.