Interactive Guide · TheCodeForge

Search & Trees:
The Ultimate Guide

An interactive journey from linear scanning to advanced tree diameter mechanics, rotated arrays, and O(1) space traversal.

Start Learning →
21 Sections
21 Live Demos
13 Algorithms
O(1) Space Morris

1. Why Searching One-by-One Breaks Down

Linear search checks every element. It's simple but brutal. If you have 1,000,000 items, it takes 1,000,000 steps. Binary search exploits sorted order to eliminate half the search space every step. Watch the difference in operations below. Target: 72.

Linear Scan vs Binary Search
Linear checks everything. Binary eliminates halves. Click the buttons to step through.

2. Binary Search on Answer: Koko Eating Bananas

Sometimes the search space isn't an array—it's a range of possible answers. Koko has h hours to eat n piles of bananas. If she eats k bananas per hour, what is the minimum k to finish in time? We binary search the "speed" (k). The isFeasible(k) function checks if a given speed works. Adjust the speed and run the simulation.

Feasibility Search Space
Adjust Koko's eating speed, then run the simulation. Piles: [3, 6, 7, 11]. Time Limit: 8h.
🔍 Go DeeperBinary Search — templates, edge cases & patterns

3. Tree Traversals: The Three Orders You Must Know

A Binary Tree is just nodes linked by edges. To process them, we use Depth-First Search (DFS). The order you visit nodes changes the use case: Inorder (Left, Root, Right) gives sorted data in a BST. Preorder (Root, Left, Right) is used to clone or serialize a tree. Postorder (Left, Right, Root) is used to delete a tree safely.

Interactive DFS Traversal
Select a traversal type and step through the recursion.
Controls & Output
Output Sequence:
[ ]
Inorder visits left, then root, then right. Preorder visits root first. Postorder visits root last.
🌳 Go DeeperBinary Tree DFS — inorder, preorder & postorder

4. Level Order Traversal: The BFS That Catches Fraud

Instead of diving deep, Breadth-First Search (BFS) explores level by level. It uses a Queue (FIFO). When you process a node, you push its children to the back of the queue. This is critical in production for finding shortest paths in unweighted graphs, routing, and fraud detection (finding connected entities within N degrees).

Queue-Based BFS Traversal
Queue State
[ ]
Visited Output
[ ]
Press "Step BFS" to dequeue a node and enqueue its children.
Go DeeperBinary Tree BFS — level order & queue patterns

5. The Diameter of a Binary Tree

The diameter is the longest path between any two nodes. It doesn't have to pass through the root! The O(n) trick is a post-order DFS: at every node, calculate the height of the left and right subtrees. The path through the current node is left_height + right_height. Track the maximum path seen, and return the height to the parent.

Longest Path Visualizer
Step through the DFS. Watch the algorithm measure heights and track the maximum path.

6. Search in Rotated Sorted Array

A sorted array has been rotated at an unknown pivot (e.g., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]). Standard binary search breaks because the halves aren't purely sorted. The trick: at every step, one half must be normally sorted. Find out which half it is, then decide if the target lies within that sorted range. Target: 0.

Pivot Discovery Visualizer
Press "Step Search" to find the target in the rotated array.

7. Serialize and Deserialize Binary Tree

To save a tree to disk or send it over a network, you must flatten it to a string. We use BFS (Level-Order) with null markers for missing children, creating the LeetCode format (e.g., [1,2,3,null,null,4,5]). Step through the serialization to see how the queue processes nulls to preserve the exact tree structure.

Tree Structure
Step through the BFS queue to build the serialized string.
LeetCode String Output
Queue State:
[ ]
Serialized String:
[ ]

8. Morris Traversal: The O(1) Space Trick

Standard Inorder traversal uses O(N) space for the call stack or an explicit stack. Morris Traversal achieves it in O(1) space. It works by temporarily modifying the tree: when traversing left, it finds the inorder predecessor (rightmost node in the left subtree) and links it back to the current node. This "thread" allows the algorithm to return to the root without a stack. Once returned, the thread is cut, restoring the original tree.

Threading Mechanism Visualizer
Step forward to see the threads (dashed yellow lines) create and remove themselves.

9. The Fenwick Tree (BIT): Range Sum Magic

A Fenwick Tree achieves O(log n) range sum queries and point updates using an array. It relies on bitwise logic: index i stores the sum of a range of elements determined by the least significant set bit of i. To get a prefix sum, you jump backwards using i -= i & (-i). To update, you jump forwards using i += i & (-i). Let's calculate the Prefix Sum of index 7.

Binary Indexed Tree Jumps
Arr:
3
1
2
2
-1
3
6
4
5
5
4
6
-3
7
Watch how index 7 jumps to 6, then to 4, then to 0 using bitwise operations.

10. Binary Tree Basics: Structure & Properties

A binary tree is a hierarchical structure where each node has at most two children — left and right. Every node has a depth (distance from root) and a height (longest path to a leaf). Click any node to inspect its properties.

Click a Node to Inspect
Click any node to see its depth, height, and type.
Node Inspector
Depth
Height
Node Type · Children:

Height = longest path to a leaf.
Depth = distance from the root.
Leaf = node with no children.
Full tree: every node has 0 or 2 children.
Complete tree: all levels filled left-to-right.

11. Binary Search Tree: Insert & Search

A BST enforces left < node < right at every level. Both insert and search are O(h) — O(log n) when balanced, O(n) in a skewed tree. Watch how each comparison halves the remaining candidates.

BST — Insert or Search a Value (default tree: 8 4 12 2 6 10 14)
Enter a value (1–20), then click Step Insert or Step Search.
🔗 Go DeeperBinary Search Tree — insert, delete & validate

12. Tree Height, Depth & Balance Factor

A tree is height-balanced if |height(left) − height(right)| ≤ 1 at every node. AVL trees enforce this. We compute height bottom-up via post-order traversal. Step through to see balance factors annotated on each node.

Balance Factor Check (post-order)
Step through bottom-up balance factor calculation.
Balance Legend
0
BF = 0 — perfectly balanced
±1
|BF| = 1 — acceptable (AVL OK)
≥2
|BF| ≥ 2 — rotation needed!

13. Lowest Common Ancestor (LCA)

The LCA of nodes A and B is the deepest node that is an ancestor of both. The elegant recursive solution: if root is null or equals A or B, return root. Otherwise recurse left and right — if both return non-null, the current node is the LCA. O(n) time, O(h) space.

Find LCA in a 7-node complete binary tree
Select two nodes and click Find LCA.

14. BST → Sorted Array: The Inorder Property

Inorder traversal of a BST (left → root → right) always yields elements in sorted ascending order. This property lets you extract a sorted array in O(n) and reconstruct a balanced BST from a sorted array in O(n). Step through to watch the array build.

Inorder traversal produces sorted output
Output will appear here...
Step through BST inorder traversal.

15. Segment Tree: Range Queries in O(log n)

A segment tree answers range sum (or min/max) queries in O(log n) with O(log n) point updates. Each node stores the aggregate of its subarray range. A query on [L,R] uses at most O(log n) nodes — it only visits nodes whose range overlaps [L,R].

Range Sum Query — Array: [2, 4, 3, 1, 6, 7, 8, 5]
Select L and R then query the range sum.

16. Trie: Prefix Search in O(k)

A trie (prefix tree) stores strings character by character. Search and insert are O(k) where k = word length. The power: all words sharing a prefix share the same path from root. Pre-loaded: apple, app, apt, bad, bat.

Trie Structure
Search or Insert
Type a word/prefix and search, or insert a new word.
Words in trie

17. AVL Tree: Self-Balancing via Rotations

AVL trees restore the balance factor (|BF| ≤ 1) after each insert via rotations. Four cases: LL (single right-rotate), RR (single left-rotate), LR (left-rotate child then right-rotate root), RL (right-rotate child then left-rotate root). Select a case and step through.

AVL Rotation Cases
Select a case above, then step through the rotation.

18. Ternary Search: Finding a Unimodal Peak

Ternary search finds the peak of a unimodal (bitonic) array by dividing it into thirds. Compare values at m1 = L + (R−L)/3 and m2 = R − (R−L)/3. Eliminate the third that can't contain the peak. O(log₃ n) — slightly slower than binary search for the same reason log₃ > log₂.

Unimodal Array — Find the Peak
Step through ternary search to find the peak value.

19. Jump Search: Block-by-Block

Jump search skips ahead in blocks of size √n until it finds a block that could contain the target, then does a linear scan backward through that block. O(√n) time — better than linear O(n) but needs a sorted array like binary search. Optimal block size is exactly √n.

Sorted Array — Target: 17
Orange = block jump. Yellow = linear backtrack. Green = found.

20. Interpolation Search: Smart Probing

For uniformly distributed sorted data, interpolation search uses: pos = lo + (target−arr[lo]) × (hi−lo) / (arr[hi]−arr[lo]). It estimates where the target likely is, rather than always going to the midpoint. Average O(log log n) — but degrades to O(n) on skewed data.

Uniform Array [10, 20 … 100] — Target: 70
Watch the probe land near the target in the first step.

21. Exponential Search: Doubling Bounds

Exponential search works on sorted arrays by first doubling the index (1 → 2 → 4 → 8…) until the value at that index exceeds the target, establishing a range. Then binary search runs within [prev, current]. O(log n) overall — ideal for unbounded or very large arrays where the target is near the beginning.

Sorted Array — Target: 11
Phase 1: doubling bounds. Phase 2: binary search in range.

Interview Questions

The 12 most common search and tree questions in engineering interviews — from FAANG to mid-stage startups. Click any question to reveal the answer.

Q01What is the difference between a binary tree and a binary search tree?
A binary tree is any tree where each node has at most two children — no ordering guarantee. A BST adds the invariant: all values in the left subtree are strictly less than the node, all values in the right subtree are strictly greater. This ordering makes search, insert and delete O(h) where h is the height — O(log n) for a balanced tree, O(n) worst case for a skewed one.
Q02What is the time and space complexity of binary search? What are its prerequisites?
Time: O(log n) — each step eliminates half the candidates. Space: O(1) iterative, O(log n) recursive due to call stack. Prerequisites: the array must be sorted and supports random access (O(1) index lookup). Binary search does not work on linked lists without modifications.
Q03What are the four types of AVL rotations and when is each triggered?
LL (Right rotation): left-heavy, left child is left-heavy. RR (Left rotation): right-heavy, right child is right-heavy. LR (Left-Right rotation): left-heavy, left child is right-heavy — first rotate left child left, then rotate root right. RL (Right-Left rotation): right-heavy, right child is left-heavy — first rotate right child right, then rotate root left. The balance factor (left height − right height) triggers rotation when |BF| ≥ 2.
Q04How does Morris inorder traversal achieve O(1) space?
Morris traversal avoids a stack by threading the tree. For each node: if no left child, visit and go right. Otherwise, find the inorder predecessor (rightmost node of left subtree). If the predecessor's right is null, set it to current (creating the thread) and go left. If it already points to current (thread exists), the left subtree is done — visit current, remove the thread, go right. The tree is fully restored after traversal.
Q05What is LCA (Lowest Common Ancestor) and how do you find it in a BST vs a general binary tree?
The LCA of two nodes p and q is the deepest node that has both p and q as descendants. In a BST: if both p and q are less than current, go left; if both greater, go right; otherwise current is the LCA — O(h) time, O(1) space. In a general binary tree: recursively search left and right subtrees; if both return non-null, current node is LCA; otherwise propagate the non-null result up — O(n) time, O(h) space.
Q06When would you use a segment tree vs a Fenwick (BIT) tree?
Both answer range queries in O(log n). Use a segment tree when you need: range updates with lazy propagation, non-prefix queries (arbitrary [l, r] range min/max/GCD), or more complex operations. Use a Fenwick tree when you only need prefix sum queries and point updates — it uses 2× less memory, has better cache locality, and the code is ~10× shorter. Fenwick trees cannot natively do range minimum queries.
Q07What is a trie and what is its time complexity for insert/search vs a hash map?
A trie (prefix tree) stores strings by sharing prefixes. Each node has up to 26 children (for lowercase ASCII). Insert and search are both O(m) where m is the key length — independent of the number of keys stored. A hash map is also O(m) amortised for hashing, but tries support prefix queries (autocomplete, prefix count) natively in O(m + output), which a hash map cannot do efficiently.
Q08How do you convert a BST to a sorted array and back?
BST → sorted array: inorder traversal (left, visit, right) produces values in ascending order — O(n) time, O(n) space including output. Sorted array → BST: pick the middle element as root, recursively build left subtree from the left half and right subtree from the right half. This produces a height-balanced BST in O(n) time. The root is always arr[mid] where mid = (lo + hi) / 2.
Q09What is the balance factor of an AVL tree and how does it differ from a Red-Black tree?
In an AVL tree, the balance factor of each node is height(left) − height(right) and must be in {-1, 0, 1}. AVL trees are more strictly balanced than Red-Black trees, so they offer faster lookups (shorter paths). Red-Black trees use a coloring invariant (no two consecutive red nodes, equal black-height on all paths) that allows slightly looser balance, resulting in fewer rotations on insert/delete. std::map in C++ and TreeMap in Java use Red-Black trees; AVL trees are preferred in read-heavy workloads.
Q10What is the difference between ternary search and binary search?
Binary search splits the range at 1 midpoint, eliminating half the space per step — O(log₂ n) comparisons. Ternary search splits at 2 points (1/3 and 2/3), eliminating one third per step — O(log₁.₅ n) steps, but each step uses 2 comparisons making it ~O(2 log₁.₅ n) ≈ O(2.4 log₂ n) total comparisons. Binary search is strictly better for sorted arrays. Ternary search is useful for unimodal functions (finding the maximum of a function with a single peak) where binary search doesn't apply.
Q11What is interpolation search and when does it outperform binary search?
Interpolation search probes at position lo + (target - arr[lo]) * (hi - lo) / (arr[hi] - arr[lo]) — it estimates where the target is based on value distribution rather than always halving. For uniformly distributed data, it achieves O(log log n) average case, beating binary search's O(log n). Worst case is O(n) for skewed distributions (e.g., exponentially growing values). It's most useful for large sorted numerical datasets with known uniform distribution — phone book lookups, sorted IP ranges.
Q12Walk through the height, depth, and level concepts in a binary tree — how are they defined and measured?
Depth of a node: number of edges from the root to that node. Root has depth 0. Height of a node: number of edges on the longest path from that node to a leaf. A leaf has height 0. Height of the tree = height of the root = longest root-to-leaf path. Level = depth + 1 (some definitions use 0-indexed levels = depth). A complete binary tree with n nodes has height ⌊log₂ n⌋. Note: some textbooks define height as number of nodes on the path (adding 1), so always clarify in interviews.
🔥
Naren Founder & Author

I've been using search algorithms and tree structures in production for over a decade — from sorted-set lookups in trading systems to segment-tree-backed range queries in data pipelines. This guide collects everything I wish had been in one place when I was learning. If it saved you a tab, share it with someone who's grinding LeetCode trees right now.

About Naren → LinkedIn ↗ Get in touch ↗