0
0
DSA Javascriptprogramming

BST vs Hash Map Trade-offs for Ordered Data in DSA Javascript - Trade-offs & Analysis

Choose your learning style9 modes available
Mental Model
A Binary Search Tree (BST) keeps data sorted and allows ordered operations, while a Hash Map stores data for fast lookup but loses order.
Analogy: Think of a BST like a sorted bookshelf where books are arranged by title, so you can find books in order or find the next one easily. A Hash Map is like a pile of books with labels, so you find a book quickly by label but can't easily find the next or previous book in order.
BST:
      5
     / \
    3   7
   / \   \
  2   4   8

Hash Map:
[ '2': bookA, '3': bookB, '4': bookC, '5': bookD, '7': bookE, '8': bookF ]
Dry Run Walkthrough
Input: Data: keys 2,3,4,5,7,8; search for key 4 and find next key after 4
Goal: Show how BST supports ordered search and next element retrieval, while Hash Map supports fast search but not ordered next element
Step 1: Search for key 4 in BST starting at root 5
5 -> [curr->3] -> 7
3 -> [curr->4] -> null
Found key 4
Why: We move left from 5 to 3 because 4 < 5, then right from 3 to 4 because 4 > 3
Step 2: Find next key after 4 in BST
4 has no right child, move up to parent 3, then up to 5
Next key is 5
Why: In BST, next key is smallest key greater than current; since 4 has no right child, we go up to find next larger key
Step 3: Search for key 4 in Hash Map
[ '2': val, '3': val, '4': val, '5': val, '7': val, '8': val ]
Found key 4 directly
Why: Hash Map uses key hashing for direct access, so search is O(1)
Step 4: Try to find next key after 4 in Hash Map
No inherent order in Hash Map keys
Cannot find next key without extra sorting
Why: Hash Map does not keep keys sorted, so ordered operations are not supported efficiently
Result:
BST final state: 2 -> 3 -> 4 -> 5 -> 7 -> 8 (in order)
Hash Map final state: keys stored unordered
Answer: BST supports ordered next key (5), Hash Map does not
Annotated Code
DSA Javascript
class BSTNode {
  constructor(key) {
    this.key = key;
    this.left = null;
    this.right = null;
    this.parent = null;
  }
}

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

  insert(key) {
    const newNode = new BSTNode(key);
    if (!this.root) {
      this.root = newNode;
      return;
    }
    let curr = this.root;
    while (true) {
      if (key < curr.key) {
        if (!curr.left) {
          curr.left = newNode;
          newNode.parent = curr;
          break;
        }
        curr = curr.left;
      } else {
        if (!curr.right) {
          curr.right = newNode;
          newNode.parent = curr;
          break;
        }
        curr = curr.right;
      }
    }
  }

  search(key) {
    let curr = this.root;
    while (curr) {
      if (key === curr.key) return curr;
      curr = key < curr.key ? curr.left : curr.right;
    }
    return null;
  }

  next(node) {
    if (node.right) {
      let curr = node.right;
      while (curr.left) curr = curr.left;
      return curr;
    }
    let curr = node;
    while (curr.parent && curr === curr.parent.right) {
      curr = curr.parent;
    }
    return curr.parent;
  }
}

class HashMap {
  constructor() {
    this.map = new Map();
  }

  insert(key, value) {
    this.map.set(key, value);
  }

  search(key) {
    return this.map.has(key) ? this.map.get(key) : null;
  }

  next(key) {
    // Hash Map does not support ordered next key
    return null;
  }
}

// Driver code
const bst = new BST();
[5,3,7,2,4,8].forEach(k => bst.insert(k));
const node = bst.search(4);
const nextNode = node ? bst.next(node) : null;

const hashMap = new HashMap();
[2,3,4,5,7,8].forEach(k => hashMap.insert(k, `val${k}`));
const hashVal = hashMap.search(4);
const hashNext = hashMap.next(4);

console.log(`BST search 4: ${node ? node.key : 'not found'}`);
console.log(`BST next after 4: ${nextNode ? nextNode.key : 'none'}`);
console.log(`HashMap search 4: ${hashVal}`);
console.log(`HashMap next after 4: ${hashNext === null ? 'none' : hashNext}`);
while (true) { if (key < curr.key) { ... } else { ... } }
Traverse BST to find correct insert position
while (curr) { if (key === curr.key) return curr; curr = key < curr.key ? curr.left : curr.right; }
Traverse BST to find node with key
if (node.right) { let curr = node.right; while (curr.left) curr = curr.left; return curr; }
Find next node in BST by going to right subtree's leftmost node
while (curr.parent && curr === curr.parent.right) { curr = curr.parent; } return curr.parent;
If no right child, move up to find next larger ancestor
return this.map.has(key) ? this.map.get(key) : null;
Hash Map direct key lookup
return null;
Hash Map does not support ordered next key
OutputSuccess
BST search 4: 4 BST next after 4: 5 HashMap search 4: val4 HashMap next after 4: none
Complexity Analysis
Time: BST operations are O(h) where h is tree height (average O(log n)), Hash Map operations are O(1) average for search but no ordered operations
Space: Both use O(n) space to store n elements
vs Alternative: BST supports ordered operations with moderate cost, Hash Map is faster for exact key lookup but cannot do ordered queries efficiently
Edge Cases
Empty BST or Hash Map
Search returns null, next returns null
DSA Javascript
if (!this.root) { this.root = newNode; return; }
Search for key not present
Returns null in both BST and Hash Map
DSA Javascript
while (curr) { if (key === curr.key) return curr; curr = key < curr.key ? curr.left : curr.right; }
Next key for largest key in BST
Returns null because no larger key exists
DSA Javascript
while (curr.parent && curr === curr.parent.right) { curr = curr.parent; } return curr.parent;
When to Use This Pattern
When a problem needs both fast key lookup and ordered data traversal, consider BST for order and Hash Map for speed; knowing their trade-offs helps choose the right structure.
Common Mistakes
Mistake: Assuming Hash Map can provide next ordered key efficiently
Fix: Remember Hash Map keys are unordered; use BST or other ordered structures for next key queries
Summary
BST keeps data sorted and supports ordered operations like finding the next key.
Use BST when you need ordered traversal or range queries; use Hash Map for fast exact key lookup.
The key insight is BST maintains order with pointers, while Hash Map uses hashing for speed but loses order.