🌳
Trees
Insert · Search · Delete · balance
18. Binary Search Tree
BSTs give O(log n) search/insert/delete if balanced — but degenerate to O(n) if not. Understand why balance matters and how production libraries (TreeMap, set) maintain it.
BSTbinary search tree
Duration
⏱ ~1 hour
Level
📊 Intermediate
Prerequisite
🎯 Lecture 17
OUTCOME
Implement BST operations and reason about balance.
What you'll learn
- 1Implement insert, search, and delete on a BST
- 2Understand why unbalanced BSTs degenerate to O(n)
- 3Know when to reach for a balanced tree (AVL, Red-Black) or skip-list
Overview
A BST maintains the property: for every node, left subtree < node < right subtree. Search and insert are O(log n) on average. The catch is balance — a sequence of sorted inserts produces a linked list with O(n) operations.
Core Concepts
1. Insert
python
def insert(root, val):
if not root:
return Node(val)
if val < root.val:
root.left = insert(root.left, val)
else:
root.right = insert(root.right, val)
return root2. Search
python
def search(root, target):
while root:
if root.val == target: return root
root = root.left if target < root.val else root.right
return None3. Delete (the tricky one)
python
def delete(root, val):
if not root: return None
if val < root.val:
root.left = delete(root.left, val)
elif val > root.val:
root.right = delete(root.right, val)
else:
# Found node to delete
if not root.left: return root.right
if not root.right: return root.left
# Two children: replace with smallest from right subtree
succ = root.right
while succ.left:
succ = succ.left
root.val = succ.val
root.right = delete(root.right, succ.val)
return root4. The balance problem
text
Insert 1, 2, 3, 4, 5 into an empty BST:
1 Degenerate into a linked list.
\ Height = N → all ops O(n).
2 No better than a list!
\
3
\
4
\
55. Balanced trees in production
- AVL trees: strict balance, faster lookup, slower insert.
- Red-Black trees: looser balance, used in C++ std::set, Java TreeMap.
- Skip lists: probabilistic alternative.
- In Python, use sortedcontainers.SortedList for production code.
Examples
Example 1 — src/01_bst.py
Build a BST with insert/search/delete.
Example 2 — src/02_inorder_sorted.py
Confirm inorder of a BST is sorted.
Example 3 — src/03_unbalanced_demo.py
Insert in sorted order to see worst-case O(n) behavior.
Example 4 — src/04_sorted_list.py
Use sortedcontainers.SortedList — the practical choice for competitive Python.
Common Mistakes
- Trying to implement AVL/Red-Black during a contest — too slow. Use SortedList.
- Forgetting BST without balance degenerates to O(n).
- Off-by-one in delete-with-two-children: pick wrong successor.
- Allowing duplicates without deciding on a convention (left or right).
Recap
- BST: left subtree < node < right subtree.
- Balance is what makes BSTs O(log n).
- In Python, prefer sortedcontainers over custom BSTs.
Try It
- BOJ 5639 (Binary search tree).
- Insert numbers 1..10 in random order and verify inorder gives sorted output.
Example code / lecture materials
All lecture materials and example code are openly available on GitHub.
View on GitHub ↗