DEV Community

Cover image for ๐Ÿ” From Data to Decisions: Understanding Binary Search Trees in JavaScript
Rakesh Reddy Peddamallu
Rakesh Reddy Peddamallu

Posted on

๐Ÿ” From Data to Decisions: Understanding Binary Search Trees in JavaScript

In the last two posts, we covered what binary trees are and how to traverse them. Now itโ€™s time to take a step further and explore a powerful, efficient variation: the Binary Search Tree (BST).

A Binary Search Tree enables fast insertion, lookup, and deletion of elements. Itโ€™s one of the most important data structures you'll come acrossโ€”especially in interviews and system design discussions.

Letโ€™s break it all down in this post:

  • What makes a tree a BST
  • How to implement one in JavaScript
  • How to insert, search, and delete values
  • Why balancing matters
  • Time complexity and real-world use cases

๐ŸŒฒ What is a Binary Search Tree?

A Binary Search Tree (BST) is a binary tree with an extra property:

For every node:

  • All values in the left subtree are less than the node's value
  • All values in the right subtree are greater than the node's value

This structure allows binary search-like efficiency, enabling fast lookups in O(log n) time (if the tree is balanced).

๐Ÿง  Visual Example:

       10
      /  \
     5    15
    / \     \
   3   7     20
Enter fullscreen mode Exit fullscreen mode
  • 5 < 10 โ†’ on the left
  • 15 > 10 โ†’ on the right
  • 3 < 5, 7 > 5, 20 > 15 โ†’ BST rules preserved

๐Ÿ›  Implementing a Binary Search Tree in JavaScript

Step 1: Node class (same as before)

class Node {
  constructor(value) {
    this.value = value;
    this.left = null;
    this.right = null;
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 2: BST class with Insert

class BinarySearchTree {
  constructor() {
    this.root = null;
  }

  insert(value) {
    const newNode = new Node(value);

    if (!this.root) {
      this.root = newNode;
      return;
    }

    let current = this.root;
    while (true) {
      if (value === current.value) return; // avoid duplicates

      if (value < current.value) {
        if (!current.left) {
          current.left = newNode;
          return;
        }
        current = current.left;
      } else {
        if (!current.right) {
          current.right = newNode;
          return;
        }
        current = current.right;
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

๐Ÿ‘‡ Example Usage:

const bst = new BinarySearchTree();
bst.insert(10);
bst.insert(5);
bst.insert(15);
bst.insert(3);
bst.insert(7);
Enter fullscreen mode Exit fullscreen mode

๐Ÿ” Searching in a BST

contains(value) {
  let current = this.root;

  while (current) {
    if (value === current.value) return true;
    current = value < current.value ? current.left : current.right;
  }

  return false;
}
Enter fullscreen mode Exit fullscreen mode

Time complexity:

  • Best/Average case: O(log n)
  • Worst case (skewed tree): O(n)

โŒ Deleting a Node in a BST

Deletion is the most complex part. There are 3 possible cases:

๐Ÿ“ฆ Case 1: Node has no children

Just remove the node.

๐Ÿ“ฆ Case 2: Node has one child

Replace the node with its child.

๐Ÿ“ฆ Case 3: Node has two children

  • Find the in-order successor (smallest value in right subtree)
  • Replace nodeโ€™s value with it
  • Recursively delete the successor
delete(value) {
  this.root = this._deleteNode(this.root, value);
}

_deleteNode(node, value) {
  if (!node) return null;

  if (value < node.value) {
    node.left = this._deleteNode(node.left, value);
  } else if (value > node.value) {
    node.right = this._deleteNode(node.right, value);
  } else {
    // Node found
    if (!node.left && !node.right) return null;
    if (!node.left) return node.right;
    if (!node.right) return node.left;

    // Two children
    let minRight = node.right;
    while (minRight.left) {
      minRight = minRight.left;
    }

    node.value = minRight.value;
    node.right = this._deleteNode(node.right, minRight.value);
  }

  return node;
}
Enter fullscreen mode Exit fullscreen mode

โš–๏ธ Time Complexity of BST Operations

Operation Best / Average Worst Case (unbalanced)
Insert O(log n) O(n)
Search O(log n) O(n)
Delete O(log n) O(n)

๐Ÿ’ก Note: When a BST becomes unbalanced (like a linked list), it loses its efficiency. This is why self-balancing trees like AVL Trees and Red-Black Trees exist.


๐Ÿง  Real-World Use Cases of BSTs

  • Implementing efficient sets or maps
  • Searching sorted hierarchical data
  • Syntax trees in compilers
  • Tree-based range queries and auto-complete systems

๐Ÿงน BST vs Binary Tree (Quick Recap)

Feature Binary Tree Binary Search Tree (BST)
Node arrangement No rules Left < Root < Right
Lookup speed O(n) O(log n) (if balanced)
Use cases Hierarchies, layouts Searching, ordered data

โœ… Summary

In this post, we:

  • Learned what makes a Binary Search Tree special
  • Built a BST class in JavaScript
  • Implemented insert, search, and delete
  • Reviewed time complexity and real-world applications

Now you have a full grasp of how BSTs work and how to implement one from scratch.

Top comments (0)