K’th smallest element in BST using O(1) Extra Space

27 Jun, 2022
Given a Binary Search Tree (BST) and a positive integer k, find the k’th smallest element in the Binary Search Tree. For example, in the following BST, if k = 3, then output should be 10, and if k = 5, then output should be 14. 
We have discussed two methods in this post and one method in this post. All of the previous methods require extra space. How to find the k’th largest element without extra space?
The idea is to use Morris Traversal. In this traversal, we first create links to Inorder successor and print the data using these links, and finally revert the changes to restore original tree. See this for more details.
Below is the implementation of the idea. 
C++
Java
Python3
C#
Javascript
// C++ program to find k'th largest element in BST#include<bits/stdc++.h>using namespace std; // A BST nodestruct Node{    int key;    Node *left, *right;}; // A function to findint KSmallestUsingMorris(Node *root, int k){    // Count to iterate over elements till we    // get the kth smallest number    int count = 0;     int ksmall = INT_MIN; // store the Kth smallest    Node *curr = root; // to store the current node     while (curr != NULL)    {        // Like Morris traversal if current does        // not have left child rather than printing        // as we did in inorder, we will just        // increment the count as the number will        // be in an increasing order        if (curr->left == NULL)        {            count++;             // if count is equal to K then we found the            // kth smallest, so store it in ksmall            if (count==k)                ksmall = curr->key;             // go to current's right child            curr = curr->right;        }        else        {            // we create links to Inorder Successor and            // count using these links            Node *pre = curr->left;            while (pre->right != NULL && pre->right != curr)                pre = pre->right;             // building links            if (pre->right==NULL)            {                //link made to Inorder Successor                pre->right = curr;                curr = curr->left;            }             // While breaking the links in so made temporary            // threaded tree we will check for the K smallest            // condition            else            {                // Revert the changes made in if part (break link                // from the Inorder Successor)                pre->right = NULL;                 count++;                 // If count is equal to K then we found                // the kth smallest and so store it in ksmall                if (count==k)                    ksmall = curr->key;                 curr = curr->right;            }        }    }    return ksmall; //return the found value} // A utility function to create a new BST nodeNode *newNode(int item){    Node *temp = new Node;    temp->key = item;    temp->left = temp->right = NULL;    return temp;} /* A utility function to insert a new node with given key in BST */Node* insert(Node* node, int key){    /* If the tree is empty, return a new node */    if (node == NULL) return newNode(key);     /* Otherwise, recur down the tree */    if (key < node->key)        node->left  = insert(node->left, key);    else if (key > node->key)        node->right = insert(node->right, key);     /* return the (unchanged) node pointer */    return node;} // Driver Program to test above functionsint main(){    /* Let us create following BST              50           /     \          30      70         /  \    /  \       20   40  60   80 */    Node *root = NULL;    root = insert(root, 50);    insert(root, 30);    insert(root, 20);    insert(root, 40);    insert(root, 70);    insert(root, 60);    insert(root, 80);     for (int k=1; k<=7; k++)       cout << KSmallestUsingMorris(root, k) << " ";     return 0;}
// Java program to find k'th largest element in BSTimport java.util.*;class GfG { // A BST nodestatic class Node{    int key;    Node left, right;} // A function to findstatic int KSmallestUsingMorris(Node root, int k){    // Count to iterate over elements till we    // get the kth smallest number    int count = 0;     int ksmall = Integer.MIN_VALUE; // store the Kth smallest    Node curr = root; // to store the current node     while (curr != null)    {        // Like Morris traversal if current does        // not have left child rather than printing        // as we did in inorder, we will just        // increment the count as the number will        // be in an increasing order        if (curr.left == null)        {            count++;             // if count is equal to K then we found the            // kth smallest, so store it in ksmall            if (count==k)                ksmall = curr.key;             // go to current's right child            curr = curr.right;        }        else        {            // we create links to Inorder Successor and            // count using these links            Node pre = curr.left;            while (pre.right != null && pre.right != curr)                pre = pre.right;             // building links            if (pre.right== null)            {                //link made to Inorder Successor                pre.right = curr;                curr = curr.left;            }             // While breaking the links in so made temporary            // threaded tree we will check for the K smallest            // condition            else            {                // Revert the changes made in if part (break link                // from the Inorder Successor)                pre.right = null;                 count++;                 // If count is equal to K then we found                // the kth smallest and so store it in ksmall                if (count==k)                    ksmall = curr.key;                 curr = curr.right;            }        }    }    return ksmall; //return the found value} // A utility function to create a new BST nodestatic Node newNode(int item){    Node temp = new Node();    temp.key = item;    temp.left = null;    temp.right = null;    return temp;} /* A utility function to insert a new node with given key in BST */static Node insert(Node node, int key){    /* If the tree is empty, return a new node */    if (node == null) return newNode(key);     /* Otherwise, recur down the tree */    if (key < node.key)        node.left = insert(node.left, key);    else if (key > node.key)        node.right = insert(node.right, key);     /* return the (unchanged) node pointer */    return node;} // Driver Program to test above functionspublic static void main(String[] args){    /* Let us create following BST            50        /     \        30     70        / \ / \    20 40 60 80 */    Node root = null;    root = insert(root, 50);    insert(root, 30);    insert(root, 20);    insert(root, 40);    insert(root, 70);    insert(root, 60);    insert(root, 80);     for (int k=1; k<=7; k++)    System.out.print(KSmallestUsingMorris(root, k) + " "); }}
# Python 3 program to find k'th# largest element in BST # A BST nodeclass Node:     # Constructor to create a new node    def __init__(self, data):        self.key = data        self.left = None        self.right = None # A function to finddef KSmallestUsingMorris(root, k):         # Count to iterate over elements    # till we get the kth smallest number    count = 0     ksmall = -9999999999 # store the Kth smallest    curr = root # to store the current node     while curr != None:                 # Like Morris traversal if current does        # not have left child rather than        # printing as we did in inorder, we        # will just increment the count as the        # number will be in an increasing order        if curr.left == None:            count += 1             # if count is equal to K then we            # found the kth smallest, so store            # it in ksmall            if count == k:                ksmall = curr.key             # go to current's right child            curr = curr.right        else:                         # we create links to Inorder Successor            # and count using these links            pre = curr.left            while (pre.right != None and                   pre.right != curr):                pre = pre.right             # building links            if pre.right == None:                                 # link made to Inorder Successor                pre.right = curr                curr = curr.left             # While breaking the links in so made            # temporary threaded tree we will check            # for the K smallest condition            else:                                 # Revert the changes made in if part                # (break link from the Inorder Successor)                pre.right = None                 count += 1                 # If count is equal to K then we                # found the kth smallest and so                # store it in ksmall                if count == k:                    ksmall = curr.key                         curr = curr.right    return ksmall # return the found value # A utility function to insert a new# node with given key in BSTdef insert(node, key):         # If the tree is empty,    # return a new node    if node == None:        return Node(key)     # Otherwise, recur down the tree    if key < node.key:        node.left = insert(node.left, key)    elif key > node.key:        node.right = insert(node.right, key)     # return the (unchanged) node pointer    return node # Driver Codeif __name__ == '__main__':         # Let us create following BST    #         50    #       /    \    #      30    70    #    /  \  /  \    #   20 40 60 80    root = None    root = insert(root, 50)    insert(root, 30)    insert(root, 20)    insert(root, 40)    insert(root, 70)    insert(root, 60)    insert(root, 80)     for k in range(1,8):        print(KSmallestUsingMorris(root, k),                                 end = " ") # This code is contributed by PranchalK
// C# program to find k'th largest element in BSTusing System; class GfG{ // A BST nodepublic class Node{    public int key;    public Node left, right;} // A function to findstatic int KSmallestUsingMorris(Node root, int k){    // Count to iterate over elements till we    // get the kth smallest number    int count = 0;     int ksmall = int.MinValue; // store the Kth smallest    Node curr = root; // to store the current node     while (curr != null)    {        // Like Morris traversal if current does        // not have left child rather than printing        // as we did in inorder, we will just        // increment the count as the number will        // be in an increasing order        if (curr.left == null)        {            count++;             // if count is equal to K then we found the            // kth smallest, so store it in ksmall            if (count==k)                ksmall = curr.key;             // go to current's right child            curr = curr.right;        }        else        {            // we create links to Inorder Successor and            // count using these links            Node pre = curr.left;            while (pre.right != null && pre.right != curr)                pre = pre.right;             // building links            if (pre.right == null)            {                // link made to Inorder Successor                pre.right = curr;                curr = curr.left;            }             // While breaking the links in so made temporary            // threaded tree we will check for the K smallest            // condition            else            {                // Revert the changes made in if part (break link                // from the Inorder Successor)                pre.right = null;                 count++;                 // If count is equal to K then we found                // the kth smallest and so store it in ksmall                if (count == k)                    ksmall = curr.key;                 curr = curr.right;            }        }    }    return ksmall; //return the found value} // A utility function to create a new BST nodestatic Node newNode(int item){    Node temp = new Node();    temp.key = item;    temp.left = null;    temp.right = null;    return temp;} /* A utility function to insert a new node with given key in BST */static Node insert(Node node, int key){    /* If the tree is empty, return a new node */    if (node == null) return newNode(key);     /* Otherwise, recur down the tree */    if (key < node.key)        node.left = insert(node.left, key);    else if (key > node.key)        node.right = insert(node.right, key);     /* return the (unchanged) node pointer */    return node;} // Driver Program to test above functionspublic static void Main(String[] args){    /* Let us create following BST            50        /     \        30     70        / \ / \    20 40 60 80 */    Node root = null;    root = insert(root, 50);    insert(root, 30);    insert(root, 20);    insert(root, 40);    insert(root, 70);    insert(root, 60);    insert(root, 80);     for (int k = 1; k <= 7; k++)    Console.Write(KSmallestUsingMorris(root, k) + " "); }} // This code has been contributed by 29AjayKumar
<script>// javascript program to find k'th largest element in BST // A BST node     class Node {            constructor() {                this.key = 0;                this.left = null;                this.right = null;            }        }      // A function to findfunction KSmallestUsingMorris(root , k){    // Count to iterate over elements till we    // get the kth smallest number    var count = 0;     var ksmall = Number.MIN_VALUE; // store the Kth smallest    var curr = root; // to store the current node     while (curr != null)    {        // Like Morris traversal if current does        // not have left child rather than printing        // as we did in inorder, we will just        // increment the count as the number will        // be in an increasing order        if (curr.left == null)        {            count++;             // if count is equal to K then we found the            // kth smallest, so store it in ksmall            if (count==k)                ksmall = curr.key;             // go to current's right child            curr = curr.right;        }        else        {            // we create links to Inorder Successor and            // count using these links            var pre = curr.left;            while (pre.right != null && pre.right != curr)                pre = pre.right;             // building links            if (pre.right== null)            {                //link made to Inorder Successor                pre.right = curr;                curr = curr.left;            }             // While breaking the links in so made temporary            // threaded tree we will check for the K smallest            // condition            else            {                // Revert the changes made in if part (break link                // from the Inorder Successor)                pre.right = null;                 count++;                 // If count is equal to K then we found                // the kth smallest and so store it in ksmall                if (count==k)                    ksmall = curr.key;                 curr = curr.right;            }        }    }    return ksmall; //return the found value} // A utility function to create a new BST nodefunction newNode(item){    var temp = new Node();    temp.key = item;    temp.left = null;    temp.right = null;    return temp;} /* A utility function to insert a new node with given key in BST */function insert(node , key){    /* If the tree is empty, return a new node */    if (node == null) return newNode(key);     /* Otherwise, recur down the tree */    if (key < node.key)        node.left = insert(node.left, key);    else if (key > node.key)        node.right = insert(node.right, key);     /* return the (unchanged) node pointer */    return node;} // Driver Program to test above functions      /* Let us create following BST            50        /     \        30     70        / \ / \    20 40 60 80 */    var root = null;    root = insert(root, 50);    insert(root, 30);    insert(root, 20);    insert(root, 40);    insert(root, 70);    insert(root, 60);    insert(root, 80);     for (k=1; k<=7; k++)    document.write(KSmallestUsingMorris(root, k) + " ");  // This code contributed by Rajput-Ji</script>
20 30 40 50 60 70 80 
Time Complexity: O(n) where n is the size of BSTAuxiliary Space: O(n)
This article is contributed by Abhishek Somani. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above
prerna saini
PranchalKatiyar
29AjayKumar
Rajput-Ji
technophpfij
hardikkoriintern
Amazon
Google
Order-Statistics
Binary Search Tree
Amazon
Google
Binary Search Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
A program to check if a binary tree is BST or not
Find postorder traversal of BST from preorder traversal
Overview of Data Structures | Set 2 (Binary Tree, BST, Heap and Hash)
Optimal Binary Search Tree | DP-24
Sorted Array to Balanced BST
Inorder Successor in Binary Search Tree
Convert a normal BST to Balanced BST
set vs unordered_set in C++ STL
Find k-th smallest element in BST (Order Statistics in BST)
Check if a given array can represent Preorder Traversal of Binary Search Tree