Find k-th smallest element in BST (Order Statistics in BST)

Given the root of a binary search tree and K as input, find K-th smallest element in BST. 
For example, in the following BST, if k = 3, then the output should be 10, and if k = 5, then the output should be 14.
 

Method 1: Using Inorder Traversal (O(n) time and O(h) auxiliary space) 
The Inorder Traversal of a BST traverses the nodes in increasing order. So the idea is to traverse the tree in Inorder. While traversing, keep track of the count of the nodes visited. If the count becomes k, print the node. 

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// A simple inorder traversal based C++ program
// to find k-th smallest element in a BST.
#include <iostream>
using namespace std;
 
// A BST node
struct Node {
    int data;
    Node *left, *right;
    Node(int x)
    {
        data = x;
        left = right = NULL;
    }
};
 
// Recursive function to insert an key into BST
Node* insert(Node* root, int x)
{
    if (root == NULL)
        return new Node(x);
    if (x < root->data)
        root->left = insert(root->left, x);
    else if (x > root->data)
        root->right = insert(root->right, x);
    return root;
}
 
// Function to find k'th largest element in BST
// Here count denotes the number of nodes processed so far
Node* kthSmallest(Node* root, int& k)
{
    // base case
    if (root == NULL)
        return NULL;
 
    // search in left subtree
    Node* left = kthSmallest(root->left, k);
 
    // if k'th smallest is found in left subtree, return it
    if (left != NULL)
        return left;
 
    // if current element is k'th smallest, return it
    k--;
    if (k == 0)
        return root;
 
    // else search in right subtree
    return kthSmallest(root->right, k);
}
 
// Function to find k'th largest element in BST
void printKthSmallest(Node* root, int k)
{
    // maintain index to count number of nodes processed so far
    int count = 0;
    Node* res = kthSmallest(root, k);
    if (res == NULL)
        cout << "There are less than k nodes in the BST";
    else
        cout << "K-th Smallest Element is " << res->data;
}
 
// main function
int main()
{
    Node* root = NULL;
    int keys[] = { 20, 8, 22, 4, 12, 10, 14 };
 
    for (int x : keys)
        root = insert(root, x);
 
    int k = 3;
    printKthSmallest(root, k);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// A simple inorder traversal based Java program
// to find k-th smallest element in a BST.
 
import java.io.*;
// A BST node
class Node {
    int data;
    Node left, right;
    Node(int x)
    {
        data = x;
        left = right = null;
    }
}
 
class GFG {
    
    static int count = 0;
    // Recursive function to insert an key into BST
    public static Node insert(Node root, int x)
    {
        if (root == null)
            return new Node(x);
        if (x < root.data)
            root.left = insert(root.left, x);
        else if (x > root.data)
            root.right = insert(root.right, x);
        return root;
    }
      
    // Function to find k'th largest element in BST
    // Here count denotes the number
    // of nodes processed so far
    public static Node kthSmallest(Node root, int k)
    {
        // base case
        if (root == null)
            return null;
      
        // search in left subtree
        Node left = kthSmallest(root.left, k);
      
        // if k'th smallest is found in left subtree, return it
        if (left != null)
            return left;
      
        // if current element is k'th smallest, return it
        count++;
        if (count == k)
            return root;
      
        // else search in right subtree
        return kthSmallest(root.right, k);
    }
      
    // Function to find k'th largest element in BST
    public static void printKthSmallest(Node root, int k)
    {
        // maintain an index to count number of
        // nodes processed so far
        count = 0;
         
        Node res = kthSmallest(root, k);
        if (res == null)
            System.out.println("There are less "
                        + "than k nodes in the BST");
        else
            System.out.println("K-th Smallest"
                    + " Element is " + res.data);
    }
         
    public static void main (String[] args) {
         
        Node root = null;
        int keys[] = { 20, 8, 22, 4, 12, 10, 14 };
      
        for (int x : keys)
            root = insert(root, x);
         
        int k = 3;
        printKthSmallest(root, k);
         
         
    }
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# A simple inorder traversal based Python3
# program to find k-th smallest element
# in a BST.
 
# A BST node
class Node:
     
    def __init__(self, key):
         
        self.data = key
        self.left = None
        self.right = None
 
# Recursive function to insert an key into BST
def insert(root, x):
     
    if (root == None):
        return Node(x)
    if (x < root.data):
        root.left = insert(root.left, x)
    elif (x > root.data):
        root.right = insert(root.right, x)
    return root
 
# Function to find k'th largest element
# in BST. Here count denotes the number
# of nodes processed so far
def kthSmallest(root):
     
    global k
     
    # Base case
    if (root == None):
        return None
 
    # Search in left subtree
    left = kthSmallest(root.left)
 
    # If k'th smallest is found in
    # left subtree, return it
    if (left != None):
        return left
         
    # If current element is k'th
    # smallest, return it
    k -= 1
    if (k == 0):
        return root
 
    # Else search in right subtree
    return kthSmallest(root.right)
 
# Function to find k'th largest element in BST
def printKthSmallest(root):
     
    # Maintain index to count number
    # of nodes processed so far
    count = 0
    res = kthSmallest(root)
     
    if (res == None):
        print("There are less than k nodes in the BST")
    else:
        print("K-th Smallest Element is ", res.data)
 
# Driver code
if __name__ == '__main__':
     
    root = None
    keys = [ 20, 8, 22, 4, 12, 10, 14 ]
 
    for x in keys:
        root = insert(root, x)
 
    k = 3
     
    printKthSmallest(root)
 
# This code is contributed by mohit kumar 29

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// A simple inorder traversal
// based C# program to find
// k-th smallest element in a BST.
using System;
 
// A BST node
class Node{
 
public int data;
public Node left, right;
public Node(int x)
{
  data = x;
  left = right = null;
}
}
 
class GFG{
    
static int count = 0;
 
// Recursive function to 
// insert an key into BST
public static Node insert(Node root,
                          int x)
{
  if (root == null)
    return new Node(x);
  if (x < root.data)
    root.left = insert(root.left, x);
  else if (x > root.data)
    root.right = insert(root.right, x);
  return root;
}
      
// Function to find k'th largest
// element in BST. Here count
// denotes the number of nodes
// processed so far
public static Node kthSmallest(Node root,
                               int k)
{
  // base case
  if (root == null)
    return null;
 
  // search in left subtree
  Node left = kthSmallest(root.left, k);
 
  // if k'th smallest is found
  // in left subtree, return it
  if (left != null)
    return left;
 
  // if current element is
  // k'th smallest, return it
  count++;
  if (count == k)
    return root;
 
  // else search in right subtree
  return kthSmallest(root.right, k);
}
 
// Function to find k'th largest
// element in BST
public static void printKthSmallest(Node root,
                                    int k)
{
  // Maintain an index to
  // count number of nodes
  // processed so far
  count = 0;
 
  Node res = kthSmallest(root, k);
   
  if (res == null)
    Console.WriteLine("There are less " +
                      "than k nodes in the BST");
  else
    Console.WriteLine("K-th Smallest" +
                      " Element is " + res.data);
}
 
// Driver code
public static void Main(String[] args)
{
 
  Node root = null;
  int []keys = {20, 8, 22, 4,
                12, 10, 14};
   
  foreach (int x in keys)
    root = insert(root, x);
 
  int k = 3;
  printKthSmallest(root, k);
}
}
 
// This code is contributed by gauravrajput1

chevron_right


Output: 

K-th Smallest Element is 10











 

We can optimize space using Morris Traversal. Please refer K’th smallest element in BST using O(1) Extra Space for details.



Method 2: Augmented  Tree Data Structure (O(h) Time Complexity and O(h) auxiliary space)
The idea is to maintain the rank of each node. We can keep track of elements in the left subtree of every node while building the tree. Since we need the K-th smallest element, we can maintain the number of elements of the left subtree in every node.
Assume that the root is having ‘lCount’ nodes in its left subtree. If K = lCount + 1, root is K-th node. If K < lCount + 1, we will continue our search (recursion) for the Kth smallest element in the left subtree of root. If K > lCount + 1, we continue our search in the right subtree for the (K – lCount – 1)-th smallest element. Note that we need the count of elements in the left subtree only.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// A simple inorder traversal based C++ program
// to find k-th smallest element in a BST.
#include <iostream>
using namespace std;
 
// A BST node
struct Node {
    int data;
    Node *left, *right;
    int lCount;
    Node(int x)
    {
        data = x;
        left = right = NULL;
        lCount = 0;
    }
};
 
// Recursive function to insert an key into BST
Node* insert(Node* root, int x)
{
    if (root == NULL)
        return new Node(x);
 
    // If a node is inserted in left subtree, then
    // lCount of this node is increased. For simplicity,
    // we are assuming that all keys (tried to be
    // inserted) are distinct.
    if (x < root->data) {
        root->left = insert(root->left, x);
        root->lCount++;
    }
 
    else if (x > root->data)
        root->right = insert(root->right, x);
    return root;
}
 
// Function to find k'th largest element in BST
// Here count denotes the number of nodes processed so far
Node* kthSmallest(Node* root, int k)
{
    // base case
    if (root == NULL)
        return NULL;
 
    int count = root->lCount + 1;
    if (count == k)
        return root;
 
    if (count > k)
        return kthSmallest(root->left, k);
 
    // else search in right subtree
    return kthSmallest(root->right, k - count);
}
 
// main function
int main()
{
    Node* root = NULL;
    int keys[] = { 20, 8, 22, 4, 12, 10, 14 };
 
    for (int x : keys)
        root = insert(root, x);
 
    int k = 4;
    Node* res = kthSmallest(root, k);
    if (res == NULL)
        cout << "There are less than k nodes in the BST";
    else
        cout << "K-th Smallest Element is " << res->data;
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// A simple inorder traversal based Java program
// to find k-th smallest element in a BST.
import java.io.*;
import java.util.*;
 
// A BST node
class Node {
    int data;
    Node left, right;
    int lCount;
    Node(int x)
    {
        data = x;
        left = right = null;
        lCount = 0;
    }
}
 
 
class Gfg
{
    // Recursive function to insert an key into BST
    public static Node insert(Node root, int x)
    {
        if (root == null)
            return new Node(x);
     
        // If a node is inserted in left subtree, then
        // lCount of this node is increased. For simplicity,
        // we are assuming that all keys (tried to be
        // inserted) are distinct.
        if (x < root.data) {
            root.left = insert(root.left, x);
            root.lCount++;
        }
     
        else if (x > root.data)
            root.right = insert(root.right, x);
        return root;
    }
     
    // Function to find k'th largest element in BST
    // Here count denotes the number of
    // nodes processed so far
    public static Node kthSmallest(Node root, int k)
    {
        // base case
        if (root == null)
            return null;
     
        int count = root.lCount + 1;
        if (count == k)
            return root;
     
        if (count > k)
            return kthSmallest(root.left, k);
     
        // else search in right subtree
        return kthSmallest(root.right, k - count);
    }
     
    // main function
    public static void main(String args[])
    {
        Node root = null;
        int keys[] = { 20, 8, 22, 4, 12, 10, 14 };
     
        for (int x : keys)
            root = insert(root, x);
     
        int k = 4;
        Node res = kthSmallest(root, k);
        if (res == null)
            System.out.println("There are less "
                           + "than k nodes in the BST");
        else
            System.out.println("K-th Smallest"
                    + " Element is " + res.data);
    }
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# A simple inorder traversal based Python3
# program to find k-th smallest element in a BST.
 
# A BST node
class newNode:
     
    def __init__(self, x):
         
        self.data = x
        self.left = None
        self.right = None
        self.lCount = 0
 
# Recursive function to insert
# an key into BST
def insert(root, x):
     
    if (root == None):
        return newNode(x)
 
    # If a node is inserted in left subtree,
    # then lCount of this node is increased.
    # For simplicity, we are assuming that
    # all keys (tried to be inserted) are
    # distinct.
    if (x < root.data):
        root.left = insert(root.left, x)
        root.lCount += 1
 
    elif (x > root.data):
        root.right = insert(root.right, x);
         
    return root
 
# Function to find k'th largest element
# in BST. Here count denotes the number
# of nodes processed so far
def kthSmallest(root, k):
     
    # Base case
    if (root == None):
        return None
         
    count = root.lCount + 1
     
    if (count == k):
        return root
 
    if (count > k):
        return kthSmallest(root.left, k)
 
    # Else search in right subtree
    return kthSmallest(root.right, k - count)
 
# Driver code
if __name__ == '__main__':
     
    root = None
    keys = [ 20, 8, 22, 4, 12, 10, 14 ]
 
    for x in keys:
        root = insert(root, x)
 
    k = 4
    res = kthSmallest(root, k)
     
    if (res == None):
        print("There are less than k nodes in the BST")
    else:
        print("K-th Smallest Element is", res.data)
         
# This code is contributed by bgangwar59

chevron_right


Output: 

K-th Smallest Element is 12











 

Time complexity: O(h) where h is the height of the tree.
Thanks to Venki for providing post. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up