DSA Binary Search Trees
A binary search tree, or BST, is a tree where every node holds one value and has at most two children. The tree follows one strict rule that keeps the data organized and makes searching fast.
Think of a game where you guess a number between 1 and 100. A friend says "higher" or "lower" after each guess. Every answer removes half of the remaining options. A BST gives a program the same power over stored data.
The BST Rule
- Every value in the left subtree is smaller than the node.
- Every value in the right subtree is larger than the node.
- Both subtrees follow the same rule.
50
/ \
30 70
/ \ / \
20 40 60 80Every number left of 50 is below 50, and every number right of 50 is above 50. Node 30 follows the same rule for its own children.
Building the Node
class Node:
def __init__(self, value):
self.value = value
self.left = None
self.right = NoneInserting a Value
Start at the root. Move left when the new value is smaller and right when it is larger. Place the new node at the first empty spot.
def insert(root, value):
if root is None:
return Node(value)
if value < root.value:
root.left = insert(root.left, value)
elif value > root.value:
root.right = insert(root.right, value)
return root
root = None
for number in [50, 30, 70, 20, 40, 60, 80]:
root = insert(root, number)
Insert 65 into the tree above
65 vs 50 -> go right
65 vs 70 -> go left
65 vs 60 -> go right
Empty spot found, place 65 as the right child of 60Searching for a Value
Searching follows the same left-or-right path as insertion.
def search(root, target):
if root is None:
return False
if target == root.value:
return True
if target < root.value:
return search(root.left, target)
return search(root.right, target)
print(search(root, 60)) # True
print(search(root, 99)) # FalseEach step discards an entire subtree. A balanced tree with 1,000,000 nodes needs only about 20 steps.
Inorder Traversal Gives Sorted Order
Visiting the left subtree, the node itself, and the right subtree in that order prints values from smallest to largest.
def inorder(root):
if root:
inorder(root.left)
print(root.value, end=" ")
inorder(root.right)
inorder(root) # 20 30 40 50 60 70 80This property makes a BST a natural way to keep sorted data.
Deleting a Node
Deletion has three cases.
Case 1: A Leaf Node
Remove the node. Nothing else changes.
Case 2: One Child
Replace the node with its only child.
Case 3: Two Children
Find the inorder successor, which is the smallest value in the right subtree. Copy that value into the node, and delete the successor from the right subtree.
def smallest(node):
while node.left:
node = node.left
return node
def delete(root, value):
if root is None:
return None
if value < root.value:
root.left = delete(root.left, value)
elif value > root.value:
root.right = delete(root.right, value)
else:
if root.left is None:
return root.right
if root.right is None:
return root.left
successor = smallest(root.right)
root.value = successor.value
root.right = delete(root.right, successor.value)
return rootThe Balance Problem
Inserting sorted numbers such as 10, 20, 30, 40 builds a tree that leans to one side.
10
\
20
\
30
\
40This tree behaves like a linked list, and every search takes O(n) time. Self-balancing trees such as AVL trees and red-black trees fix the lean automatically.
Complexity Summary
- Search, insert, delete (balanced): O(log n)
- Search, insert, delete (skewed): O(n)
- Space: O(n) to store the nodes
Real-Life Uses
Databases build tree-based indexes so a lookup skips most of the stored records. Autocomplete features keep sorted word lists for quick range searches. Language libraries use balanced trees inside ordered maps and sets. A contact app can keep names sorted so every new entry lands in the correct spot instantly.
Common Mistakes
Many learners compare only a node with its direct children and miss the rule for the whole subtree. Every value on the left side must stay below the node, even deep inside the branch. Duplicate values need a clear policy, such as ignoring repeats or keeping a count in each node. Draw the tree after every insert to catch rule violations early.
Key Points
- A BST keeps smaller values on the left and larger values on the right.
- Insert and search follow one path from the root downward.
- Inorder traversal returns values in sorted order.
- Deleting a node with two children uses the inorder successor.
- A skewed tree loses its speed advantage.
- Balanced variants keep operations at O(log n).
