Given a binary search tree, task is to find Kth largest element in the binary search tree.
Example:
Input : k = 3
Root of following BST
10
/ \
4 20
/ / \
2 15 40
Output : 15
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.
Algorithm
1) Initialize Current as root.
2) Initialize a count variable to 0.
3) While current is not NULL :
3.1) If current has no right child
a) Increment count and check if count is equal to K.
1) If count is equal to K, simply return current
Node as it is the Kth largest Node.
b) Otherwise, Move to the left child of current.
3.2) Else, here we have 2 cases:
a) Find the inorder successor of current Node.
Inorder successor is the left most Node
in the right subtree or right child itself.
b) If the left child of the inorder successor is NULL:
1) Set current as the left child of its inorder
successor.
2) Move current Node to its right.
c) Else, if the threaded link between the current Node
and it's inorder successor already exists :
1) Set left pointer of the inorder successor as NULL.
2) Increment count and check if count is equal to K.
a) If count is equal to K, simply return current
Node as it is the Kth largest Node.
3) Otherwise, Move current to it's left child.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node *left, *right;
};
Node* newNode( int data)
{
Node* temp = new Node;
temp->data = data;
temp->right = temp->left = NULL;
return temp;
}
Node* KthLargestUsingMorrisTraversal(Node* root, int k)
{
Node* curr = root;
Node* Klargest = NULL;
int count = 0;
while (curr != NULL) {
if (curr->right == NULL) {
if (++count == k)
Klargest = curr;
curr = curr->left;
}
else {
Node* succ = curr->right;
while (succ->left != NULL && succ->left != curr)
succ = succ->left;
if (succ->left == NULL) {
succ->left = curr;
curr = curr->right;
}
else {
succ->left = NULL;
if (++count == k)
Klargest = curr;
curr = curr->left;
}
}
}
return Klargest;
}
int main()
{
Node* root = newNode(4);
root->left = newNode(2);
root->right = newNode(7);
root->left->left = newNode(1);
root->left->right = newNode(3);
root->right->left = newNode(6);
root->right->right = newNode(10);
cout << "Finding K-th largest Node in BST : "
<< KthLargestUsingMorrisTraversal(root, 2)->data;
return 0;
}
|
Java
class GfG
{
static class Node
{
int data;
Node left, right;
}
static Node newNode( int data)
{
Node temp = new Node();
temp.data = data;
temp.right = null ;
temp.left = null ;
return temp;
}
static Node KthLargestUsingMorrisTraversal(Node root, int k)
{
Node curr = root;
Node Klargest = null ;
int count = 0 ;
while (curr != null )
{
if (curr.right == null )
{
if (++count == k)
Klargest = curr;
curr = curr.left;
}
else
{
Node succ = curr.right;
while (succ.left != null && succ.left != curr)
succ = succ.left;
if (succ.left == null )
{
succ.left = curr;
curr = curr.right;
}
else
{
succ.left = null ;
if (++count == k)
Klargest = curr;
curr = curr.left;
}
}
}
return Klargest;
}
public static void main(String[] args)
{
Node root = newNode( 4 );
root.left = newNode( 2 );
root.right = newNode( 7 );
root.left.left = newNode( 1 );
root.left.right = newNode( 3 );
root.right.left = newNode( 6 );
root.right.right = newNode( 10 );
System.out.println( "Finding K-th largest Node in BST : " +
KthLargestUsingMorrisTraversal(root, 2 ).data);
}
}
|
Python3
class newNode:
def __init__( self , data):
self .data = data
self .right = self .left = None
def KthLargestUsingMorrisTraversal(root, k):
curr = root
Klargest = None
count = 0
while (curr ! = None ):
if (curr.right = = None ):
count + = 1
if (count = = k):
Klargest = curr
curr = curr.left
else :
succ = curr.right
while (succ.left ! = None and
succ.left ! = curr):
succ = succ.left
if (succ.left = = None ):
succ.left = curr
curr = curr.right
else :
succ.left = None
count + = 1
if (count = = k):
Klargest = curr
curr = curr.left
return Klargest
if __name__ = = '__main__' :
root = newNode( 4 )
root.left = newNode( 2 )
root.right = newNode( 7 )
root.left.left = newNode( 1 )
root.left.right = newNode( 3 )
root.right.left = newNode( 6 )
root.right.right = newNode( 10 )
print ( "Finding K-th largest Node in BST : " ,
KthLargestUsingMorrisTraversal(root, 2 ).data)
|
C#
using System;
using System.Collections.Generic;
class GfG
{
public class Node
{
public int data;
public Node left, right;
}
static Node newNode( int data)
{
Node temp = new Node();
temp.data = data;
temp.right = null ;
temp.left = null ;
return temp;
}
static Node KthLargestUsingMorrisTraversal(Node root, int k)
{
Node curr = root;
Node Klargest = null ;
int count = 0;
while (curr != null )
{
if (curr.right == null )
{
if (++count == k)
Klargest = curr;
curr = curr.left;
}
else
{
Node succ = curr.right;
while (succ.left != null && succ.left != curr)
succ = succ.left;
if (succ.left == null )
{
succ.left = curr;
curr = curr.right;
}
else
{
succ.left = null ;
if (++count == k)
Klargest = curr;
curr = curr.left;
}
}
}
return Klargest;
}
public static void Main(String[] args)
{
Node root = newNode(4);
root.left = newNode(2);
root.right = newNode(7);
root.left.left = newNode(1);
root.left.right = newNode(3);
root.right.left = newNode(6);
root.right.right = newNode(10);
Console.Write( "Finding K-th largest Node in BST : " +
KthLargestUsingMorrisTraversal(root, 2).data);
}
}
|
Javascript
<script>
class Node
{
constructor(){
this .data = 0;
this .left = null ;
this .right = null ;
}
}
function newNode(data)
{
var temp = new Node();
temp.data = data;
temp.right = null ;
temp.left = null ;
return temp;
}
function KthLargestUsingMorrisTraversal(root , k)
{
var curr = root;
var Klargest = null ;
var count = 0;
while (curr != null )
{
if (curr.right == null )
{
if (++count == k)
Klargest = curr;
curr = curr.left;
}
else
{
var succ = curr.right;
while (succ.left != null && succ.left != curr)
succ = succ.left;
if (succ.left == null )
{
succ.left = curr;
curr = curr.right;
}
else
{
succ.left = null ;
if (++count == k)
Klargest = curr;
curr = curr.left;
}
}
}
return Klargest;
}
root = newNode(4);
root.left = newNode(2);
root.right = newNode(7);
root.left.left = newNode(1);
root.left.right = newNode(3);
root.right.left = newNode(6);
root.right.right = newNode(10);
document.write( "Finding K-th largest Node in BST : " +
KthLargestUsingMorrisTraversal(root, 2).data);
</script>
|
Output
Finding K-th largest Node in BST : 7
Complexity Analysis:
- Time Complexity : O(n)
- Auxiliary Space : O(1)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
12 Aug, 2022
Like Article
Save Article