Open In App

Kth Largest/Smallest Element in Binary Search Tree using JavaScript

Last Updated : 26 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

A binary search tree is a type of binary tree in which each node has two children: left child & right child. In a Binary search tree (BST) all nodes in the left subtree have values less than the node value and all nodes in the right subtree have values greater than the node value.

Different approaches to find the Kth largest/smallest element in a Binary Search Tree are

Using In-order Traversal

We will create a function to perform an in-order traversal of a BST, storing elements in ascending order. Then, another function, kthLargestAndSmallest, will use this traversal to find the kth smallest and largest elements in the tree.

Example: The below code traverse the BST in the in-order manner to find kth largest and smallest elements.

JavaScript
class TreeNode {
    constructor(val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
}
function inorderTraversal(root, inorder) {
    if (!root) return;
    inorderTraversal(root.left, inorder);
    inorder.push(root.val);
    inorderTraversal(root.right, inorder);
}
function kthLargestAndSmallest(root, k) {
    const inorder = [];
    inorderTraversal(root, inorder);
    const n = inorder.length;
    if (k > n || k <= 0) {
        return null;
    }
    const kthSmallest = inorder[k - 1];
    const kthLargest = inorder[n - k];
    return { kthSmallest, kthLargest };
}
const root = new TreeNode(5);
root.left = new TreeNode(3);
root.right = new TreeNode(6);
root.left.right = new TreeNode(4);
root.left.left = new TreeNode(2);
root.right.right = new TreeNode(8);
console.log(kthLargestAndSmallest(root, 2)); 

Output
{ kthSmallest: 3, kthLargest: 6 }

Time Complexity: O(n)

Space Complexity: O(n)

Iterative Approach

We will define two functions, kthSmallest and kthLargest, both utilizing iterative in-order traversal with a stack. In kthSmallest, we traverse left until no more left child, decrementing k until it’s 0, then return the current node value. Similarly, in kthLargest, we traverse right until no more right child, decrementing k until it’s 0, then return the current node value.

Example: The below code iteratively traverses the BST and returns kth largest and smallest elements.

JavaScript
class TreeNode {
    constructor(val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
}

function kthSmallest(root, k) {
    const stack = [];
    let curr = root;
    while (curr || stack.length) {
        while (curr) {
            stack.push(curr);
            curr = curr.left;
        }

        curr = stack.pop();
        k--;
        if (k === 0) return curr.val;

        curr = curr.right;
    }
    return null;
}

function kthLargest(root, k) {
    const stack = [];
    let curr = root;
    while (curr || stack.length) {
        while (curr) {
            stack.push(curr);
            curr = curr.right;
        }

        curr = stack.pop();
        k--;
        if (k === 0) return curr.val;

        curr = curr.left;
    }
    return null;
}
const root = new TreeNode(5);
root.left = new TreeNode(3);
root.right = new TreeNode(6);
root.left.right = new TreeNode(4);
root.left.left = new TreeNode(2);
root.right.right = new TreeNode(8);
console.log(kthLargest(root, 2));
console.log(kthSmallest(root, 2));

Output
6
3

Time Complexity : O(h+k) , where h is height of BST.

Space Complexity : O(h)

Using Recursive Approach

We will define a function, inorderTraversal, to recursively perform an in-order traversal of the BST. Then, in kthSmallest, we will use this traversal to populate an array with elements in ascending order and return the kth element. Similarly, in kthLargest, we will populate the array in reverse order and return the kth element for the largest.

Example: The below code implements recursive in-order traversal to traverse the tree and find specified elements.

JavaScript
class TreeNode {
    constructor(val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
}

function inorderTraversal(root, arr) {
    if (!root) return;
    inorderTraversal(root.left, arr);
    arr.push(root.val);
    inorderTraversal(root.right, arr);
}

function kthSmallest(root, k) {
    const inorder = [];
    inorderTraversal(root, inorder);
    return inorder[k - 1];
}

function kthLargest(root, k) {
    const inorder = [];
    inorderTraversal(root, inorder);
    return inorder[inorder.length - k];
}
const root = new TreeNode(5);
root.left = new TreeNode(3);
root.right = new TreeNode(6);
root.left.right = new TreeNode(4);
root.left.left = new TreeNode(2);
root.right.right = new TreeNode(8);
console.log(kthLargest(root, 2));
console.log(kthSmallest(root, 2));

Output
6
3

Time Complexity : O(n)

Space Complexity : O(n)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads