Data Structure
Binary Search Tree
“The Unbalanced Ancestor”
History
The Binary Search Tree (BST) is the grandfather of modern hierarchical data structures. While the concept of binary search on arrays existed earlier, the dynamic pointer-based tree structure emerged in the 1960s as a way to handle changing datasets.
It is the simplest form of a "sorted" tree. It represents the ideal of performance, but without any safety rails to guarantee it.
Core Property
The Binary Search Property
For every node, all nodes in its Left Subtree are smaller, and all nodes in its Right Subtree are larger. This simple rule allows us to cut the search space in half with every step down the tree.
How It Works
A BST relies on simple comparisons to navigate.
The Mechanics
- Search: Start at the root. If the value is what you want, stop. If smaller, go left. If larger, go right. Repeat.
- Insert: Perform a search until you hit a "null" spot (a dead end). Plant the new node there.
- Delete: This is the tricky part.
- Leaf node: Just snip it off.
- One child: Replace the node with its child.
- Two children: Find the "In-Order Successor" (smallest node in the right subtree), swap values, and delete that successor.
Time depends on height ($h$). In a balanced tree, $h = log n$. In a line, $h = n$.
We have to traverse from root to leaf to find the insertion spot.
Finding the node and its successor takes time proportional to the tree's depth.
We need to store every element. No extra overhead for balancing metadata.
Code Walkthrough
Complete data structure implementations in multiple programming languages. Select a language to view idiomatic code.
1class TreeNode:2 """Node for Binary Search Tree."""3 def __init__(self, val: int):4 self.val = val5 self.left: TreeNode | None = None6 self.right: TreeNode | None = None789class BST:10 """Binary Search Tree with insert, search, and delete operations."""11 def __init__(self):12 self.root: TreeNode | None = None1314 def insert(self, val: int) -> None:15 """Insert a value into the BST."""16 if not self.root:17 self.root = TreeNode(val)18 return1920 curr = self.root21 while True:22 if val < curr.val:23 if curr.left is None:24 curr.left = TreeNode(val)25 return26 curr = curr.left27 else:28 if curr.right is None:29 curr.right = TreeNode(val)30 return31 curr = curr.right3233 def search(self, val: int) -> TreeNode | None:34 """Search for a value in the BST."""35 curr = self.root36 while curr:37 if val == curr.val:38 return curr39 elif val < curr.val:40 curr = curr.left41 else:42 curr = curr.right43 return None4445 def delete(self, val: int) -> None:46 """Delete a value from the BST."""47 self.root = self._delete_recursive(self.root, val)4849 def _delete_recursive(self, node: TreeNode | None, val: int) -> TreeNode | None:50 if not node:51 return None5253 if val < node.val:54 node.left = self._delete_recursive(node.left, val)55 elif val > node.val:56 node.right = self._delete_recursive(node.right, val)57 else:58 # Node found - handle three cases59 if not node.left:60 return node.right61 if not node.right:62 return node.left6364 # Two children: find in-order successor65 successor = self._find_min(node.right)66 node.val = successor.val67 node.right = self._delete_recursive(node.right, successor.val)6869 return node7071 def _find_min(self, node: TreeNode) -> TreeNode:72 """Find the minimum value node in a subtree."""73 while node.left:74 node = node.left75 return nodeReal World Use Cases
- 1Educational introduction to tree algorithms
- 2Simple lookups where data arrives in random order
- 3Implementing Sets and Maps (conceptually)
- 4Sorting streams of data
Key Insights
- It provides ordered traversal () for free.
- It is sensitive to input order.
- It has no overhead for maintaining balance.
- All operations depend on the height of the tree.
When to Use
Use a vanilla BST for simple tasks, educational purposes, or when you know your input data is randomized enough that the tree won't become a line.
When NOT to Use
Do not use in production if the data might be pre-sorted. Inserting sorted data into a BST turns it into a Linked List with extra steps.
Watch Out
The Degenerate Case: If you insert 1, 2, 3, 4, 5 in order, you don't get a tree. You get a line. Complexity degrades to .