I Finally Understood BST — And It's Just Divide & Conquer in Disguise
Last article, I said trees made me nervous. Recursion. Nodes. Children. Height. I expected to be stuck for a week like linked lists. I wasn't. Binary Search Tree clicked faster than I expected — and once it did, I understood why every other tree conc...
Last article, I said trees made me nervous.
Recursion. Nodes. Children. Height. I expected to be stuck for a week like linked lists.
I wasn't.
Binary Search Tree clicked faster than I expected — and once it did, I understood why every other tree concept builds on top of it.
Here's what actually made it click.
The One Rule That Controls Everything
A BST is a binary tree with one simple rule:
- Left child = smaller values
- Right child = larger values
That's it. One rule. And it controls everything — search, insert, delete.
I kept trying to memorize BST as a definition. The moment I stopped memorizing and started seeing the pattern, it opened up.
The Pattern: BST Is Just Divide & Conquer
Say you're searching for 40 in this tree:
50
/ \
30 70
/ \ / \
20 40 60 80
Step by step:
- 40 < 50 → ignore the entire right subtree
- Move left to 30
- 40 > 30 → ignore the left subtree
- Move right → found 40
At every single step, we eliminated half the remaining tree.
That is Divide and Conquer. The same mental model behind Binary Search. The same idea I'd been using on arrays — just applied to a tree structure.
That's when it stopped being scary and became logical.
Why BST Is Fast (Or Not)
All BST operations depend on one thing: height of the tree.
Average case (balanced tree):
Height ≈ log n
| Operation | Time |
| Search | O(log n) |
| Insert | O(log n) |
| Delete | O(log n) |
We eliminate half the tree at each step — same reason binary search is O(log n).
Worst case (skewed tree):
If you insert values in sorted order — say 10, 20, 30, 40 — the tree degenerates into this:
10
\
20
\
30
\
40
It's just a linked list wearing a tree costume. Height becomes n, and every operation becomes O(n).
This is why balanced trees exist — AVL, Red-Black. BST is powerful, but only if it stays balanced.
Understanding this made me realize: data structure efficiency isn't just about the structure. It's about the shape of data going in.
Building BST in Python
Let's implement it.
Node class:
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
BST class with insert:
class Node:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
class BST:
def __init__(self):
self.root = None
def insert(self, value):
if self.root is None:
self.root = Node(value)
else:
self._insert(self.root, value)
def _insert(self, current, value):
if value < current.value:
if current.left is None:
current.left = Node(value)
else:
self._insert(current.left, value)
elif value > current.value:
if current.right is None:
current.right = Node(value)
else:
self._insert(current.right, value)
Search — two versions:
Recursive (good for understanding):
def contains(self, value):
return self._contains(self.root, value)
def _contains(self, current, value):
if current is None:
return False
if value == current.data:
return True
elif value < current.data:
return self._contains(current.left, value)
else:
return self._contains(current.right, value)
Iterative (preferred in interviews):
def contains(self, value):
current = self.root
while current:
if value == current.data:
return True
elif value < current.data:
current = current.left
else:
current = current.right
return False
I learned both. But in interviews, the iterative version signals that you understand the mechanics, not just the pattern.
Search (Contains) Operation
Same divide and conquer logic — start at root, go left if smaller, right if bigger.
Iterative version (easier to read):
def contains(self, value):
current = self.root
while current:
if value == current.data:
return True
elif value < current.data:
current = current.left
else:
current = current.right
return False
Plain English: start at root, keep moving left or right until you find the value or run out of nodes.
Recursive version (function calls itself):
def contains(self, value):
return self._contains(self.root, value)
def _contains(self, current, value):
if current is None: # base case — stop here
return False
if value == current.data:
return True
elif value < current.data:
return self._contains(current.left, value) # call itself on left
else:
return self._contains(current.right, value) # call itself on right
Both versions do the exact same thing. The iterative one uses a while loop. The recursive one calls itself with a smaller piece of the problem each time — until it either finds the value or hits None (that if current is None line is what stops it from running forever).
I'm still getting comfortable with recursion honestly. But the mental model that helped me: imagine passing the task to a junior version of yourself, with a smaller problem each time. Eventually the problem is so small the answer is obvious.
What BST Actually Taught Me
The biggest takeaway wasn't the code.
It was this: the structure of your data determines the performance of your operations.
A balanced BST gives you O(log n). The same BST with sorted input gives you O(n). Same code, completely different performance — just because of insertion order.
That's a mindset shift. You can't just write correct code. You have to think about what your data looks like in practice.
Current Stats
Day in journey: ~15
Topics completed: Linked Lists, Stacks, Queues, BST
Daily study time: 4 hours
Confidence with BST: Solid on search and insert. Delete is next — and apparently the tricky one.
LeetCode progress: Still building pattern recognition. Still humbling. 😅
What's Next
BST deletion (three cases — and one of them is genuinely tricky), tree traversals (inorder, preorder, postorder), and eventually balanced trees.
If linked lists were the foundation, BST feels like the first floor. Everything that comes next — AVL trees, heaps, tries — builds on understanding this structure deeply.
Recursion still feels uncomfortable. But I'm getting more fluent with it each day.
If you're learning DSA too — the "divide and conquer" mental model will carry you further than any definition. Find the pattern, not the memorization.
That's the real skill.
Next up: BST Deletion and Tree Traversals
Goal: All DSA in 2 months → 300+ LeetCode problems
Following along? Drop a comment — what clicked for you, and what didn't.
— Avinash Negi
Useful Resources:
- Scott Barrett's Python DSA Course on Udemy
- Previous: Stacks, Queues, and Why O(1) vs O(n) Finally Clicked
This article was originally published on Hashnode by Avinash Negi.