Kth Smallest element in a Perfect Binary Search Tree

Given a Perfect BST with N nodes and an integer K, the task is to find the Kth smallest element in present in the tree.

Example:

Input:
K = 3, N = 15
               50 
            /     \ 
          30        70 
         /  \      /  \ 
       20   40    60    80
       /\   /\    /\    / \
     14 25 35 45 55 65 75  85   
Output: 25

Explanation: 
The 3rd smallest element
in the given BST is 25


Input: 
K = 9, N = 15
              50 
           /       \ 
          30        70 
         /  \      /  \ 
       20   40    60    80
       /\   /\    /\    / \
     14 25 35 45 55 65 75  85    
Output: 55

Explanation: 
The 9th smallest element
in the given BST is 55 

Naive Approach: Do the Inorder traversal in a perfect BST, such as morris traversal or recursive solution, which visits every node and return the kth visit key. It takes O(N) time complexity to complete the task. 

Efficient Approach: 
Since the given BST is perfect and the number of nodes of the entire tree is already known, the computational complexity to solve the problem can be reduced to log(N). Follow the steps given below to solve the problem:

  • Calculate the median of every sub-tree by dividing the total nodes in the tree(N) as |N| / 2.
  • The left sub-tree of the Perfect BST will always contain nodes with smaller value than K nodes if :
    • K < location(median(N))
  • The right sub-tree of Perfect BST will always contain nodes with greater value than K nodes if :
    • K > location(median(N)), in this case, Kth smallest element for right sub-tree is K – location(median(N)).
  • Since |N| will always be odd in a perfect binary tree, the location of the median in any perfect BST is |N|/2 + 1.
  • If K is location(median(T)), then that node contains the Kth smallest element in perfect BST.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find K-th
// smallest element in a
// perfect BST
#include <bits/stdc++.h>
using namespace std;
  
// A BST node
struct Node {
    int key;
    Node *left, *right;
};
  
// A utility function to
// create a new BST node
Node* 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
    if (node == NULL)
        return newNode(key);
  
    // Recur down the left
    // subtree for smaller values
    if (key < node->key)
        node->left = insert(node->left, key);
  
    // Recur down the right
    // subtree for smaller values
    else if (key > node->key)
        node->right = insert(node->right, key);
  
    // Return the (unchanged) node pointer
    return node;
}
// FUnction to find Kth Smallest
// element in a perfect BST
bool KSmallestPerfectBST(
    Node* root, int k, int treeSize,
    int& kth_smallest)
{
    if (root == NULL)
        return false;
  
    // Find the median
    int median_loc = (treeSize / 2) + 1;
  
    // If the element is at
    // the median
    if (k == median_loc) {
  
        kth_smallest = root->key;
        return true;
    }
  
    // Round down the search space
    int newTreeSize = treeSize / 2;
  
    // If median is located higher
    if (k < median_loc) {
        return KSmallestPerfectBST(
            root->left, k, newTreeSize,
            kth_smallest);
    }
  
    // If median is located lower
    int newK = k - median_loc;
    return KSmallestPerfectBST(
        root->right, newK, newTreeSize,
        kth_smallest);
}
  
// Driver Code
int main()
{
    /* Let us create following BST
               50
           /       \
          30        70
         /  \      /  \
       20   40    60    80
       /\   /\    /\    / \
     14 25 35 45 55 65 75  85
       */
    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);
    insert(root, 14);
    insert(root, 25);
    insert(root, 35);
    insert(root, 45);
    insert(root, 55);
    insert(root, 65);
    insert(root, 75);
    insert(root, 85);
  
    int n = 15, k = 5;
    int ans = -1;
    if (KSmallestPerfectBST(
            root, k, n, ans)) {
  
        cout << ans << " ";
    }
  
    return 0;
}

chevron_right


Output:

35

Time complexity: O(Log(N))
Auxiliary Space: O(Log(N))

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

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.