Exercises — Level-order traversal — BFS with queue
We reuse one running tree for most exercises so you can compare answers. Here it is, drawn as floors:

Level 1 — Recognition
Recall Solution 1.1
Read floor by floor:
- Floor 0:
1 - Floor 1:
2 3 - Floor 2:
4 5 6 - Floor 3:
7
Output: 1 2 3 4 5 6 7.
That is literally reading the picture top-to-bottom, left-to-right — which is exactly what BFS with a queue produces.
Recall Solution 1.2
A queue (FIFO). We remove from the front with dequeue (popleft in Python). A Stack (LIFO) would pop the most-recently-added node and dive deep, giving Depth-First Search (DFS) order instead.
Recall Solution 1.3
Levels: 0,1,2,3 → 4 levels.
Height counts edges on the longest path (root → 2 → 5 → 7): that is 3 edges, so .
Note: number of levels = . A common slip is to confuse the two.
Level 2 — Application
Recall Solution 2.1
Snapshot n = len(queue) at the start of each round:
- Round 1:
n=1, process1, enqueue2,3→[1] - Round 2:
n=2, process2,3, enqueue4,5(from 2) and6(from 3) →[2,3] - Round 3:
n=3, process4,5,6; node5enqueues7→[4,5,6] - Round 4:
n=1, process7→[7]
Output: [[1],[2,3],[4,5,6],[7]].
Recall Solution 2.2
| Step | Dequeue | Queue after |
|---|---|---|
| init | [1] |
|
| 1 | 1 | [2,3] |
| 2 | 2 | [3,4,5] |
| 3 | 3 | [4,5,6] |
| 4 | 4 | [5,6] |
| 5 | 5 | [6,7] |
| 6 | 6 | [7] |
| 7 | 7 | [] |
Max queue size reached = 3 (after step 2). This equals the tree's max width (floor 2 holds 4,5,6).
Recall Solution 2.3
Index → value: 0:1, 1:2, 2:3, 3:4, 4:5, 5:null, 6:6.
1(idx 0): children idx 1,2 =2,32(idx 1): children idx 3,4 =4,53(idx 2): children idx 5,6 =null,6→ only right child6
Tree:
1
/ \
2 3
/ \ \
4 5 6
Flat BFS = read the array skipping null: 1 2 3 4 5 6.
Level 3 — Analysis
Recall Solution 3.1
Stack, push order = left then right, so right is on top and pops first.
- push
1. Pop1; push2,3→ stack[2,3](3 on top). - Pop
3;3has right child6→ push6→[2,6]. - Pop
6(leaf) →[2]. - Pop
2; push4,5→[4,5](5 on top). - Pop
5;5has child7→ push7→[4,7]. - Pop
7(leaf) →[4]. - Pop
4(leaf) →[].
Order: 1 3 6 2 5 7 4. This is a depth-first pre-order that follows the right branch first (because we pushed left first, so right sits on top). It is not level order — proving the container choice is what encodes the traversal.
Recall Solution 3.2
From the trace in 2.2 the queue sizes were 1,2,3,2,2,1,0 → max = 3.
- Width (floor
4,5,6). Height . - The queue holds ~one level's worth of nodes, so BFS space is , here .
- Contrast: DFS's stack holds one path, so , here also .
They happen to match on this small tree, but they diverge on shape: see Tree height vs width. On a wide tree BFS costs more; on a deep skewed tree DFS costs more.
Recall Solution 3.3
Each outer round starts by snapshotting n = len(queue). Claim: at the start of round (1-indexed) the queue contains exactly all nodes of level , and nothing else.
Base: round 1 starts with just the root = all of level 0. ✓ Inductive step: suppose round starts holding exactly level . The inner loop processes all of them, and enqueues only their children, which are precisely the nodes of level (a tree node has a unique parent, so no duplicates, no gaps). After the inner loop the queue holds exactly level . ✓
The loop stops when the queue is empty — i.e. after the round that processed the last non-empty level. So the outer loop runs once per level.
Level 4 — Synthesis
Recall Solution 4.1
Keep normal BFS (children always enqueued left→right so the queue stays honest); only reverse the emitted list on odd levels.
- Level 0 (even):
[1] - Level 1 (odd): natural
[2,3]→ reversed[3,2] - Level 2 (even):
[4,5,6] - Level 3 (odd): natural
[7]→ reversed[7]
Output: [[1],[3,2],[4,5,6],[7]].
Change: keep a boolean left_to_right; after building each level list, if not left_to_right: level.reverse(), then flip the boolean. Do not reverse the enqueue order — that would corrupt the next level's ordering.
Recall Solution 4.2
During grouped BFS, the last node dequeued in each round is that level's rightmost.
- Level 0 last:
1 - Level 1 last:
3 - Level 2 last:
6 - Level 3 last:
7
Output: [1,3,6,7].
Because we process each level as a contiguous block of size n, the node at inner-loop index n-1 is exactly the rightmost — no extra bookkeeping needed.
Recall Solution 4.3
Tag each node with dist = parent.dist + 1, root dist = 0.
1→0, 2→1, 3→1, 4→2, 5→2, 6→2, 7→3.
Distance to 7 = 3 edges.
BFS expands nodes in increasing distance order, so the first time you reach a node you have used the fewest edges — that is the shortest path in an unweighted graph. On a tree the answer is just the node's depth.
Level 5 — Mastery
Recall Solution 5.1
(a) 0:3, 1:9, 2:20, 3:null, 4:null, 5:15, 6:7.
3(idx0) children idx1,2 =9,209(idx1) children idx3,4 =null,null→ leaf20(idx2) children idx5,6 =15,7
3
/ \
9 20
/ \
15 7
(b) Grouped: [[3],[9,20],[15,7]].
(c) Widths per level: 1,2,2 → . Max queue size during flat BFS = 2.
(d) Nodes present . Time (each node enqueued/dequeued once). Space .
Recall Solution 5.2
(a) Bottom level (level ) has nodes. (b) The queue peaks holding the whole bottom level, so space . Since , we get So BFS space is in the worst case. (c) : , bottom level . Indeed , close to .
Recall Solution 5.3
A left path: root → child → child → … ( nodes, one per level, so the queue never holds more than 1 waiting element after each step).
- With
deque:popleft()is . Total work . ✓ - With
list.pop(0): eachpop(0)shifts all remaining elements → . Even though this path keeps the list short, take instead the complete tree where the queue holds up to nodes: each of the dequeues at the widest level costs up to to shift → summed cost .
Concrete count for a complete tree of nodes: the widest queue state has elements; the total element-shifts across all pop(0) calls grows quadratically, whereas deque.popleft() performs exactly constant-time removals.
Fix: always use collections.deque + popleft() for BFS queues.
Flat BFS output of the running tree (root 1, kids 2/3, then 4/5 under 2, 6 under 3, 7 under 5)
1 2 3 4 5 6 7Grouped BFS output of the running tree
[[1],[2,3],[4,5,6],[7]]Max queue size during flat BFS of the running tree, and what it equals
Right-side view (rightmost per level) of the running tree
[1,3,6,7]Worst-case BFS space as a fraction of n for a perfect tree
Connections
- Parent topic — the algorithm these exercises drill.
- Breadth-First Search (BFS) · Depth-First Search (DFS) · Queue (FIFO) data structure · Stack (LIFO)
- Binary Tree representation — array form used in Ex 2.3, 5.1.
- Shortest path in unweighted graphs — Ex 4.3. · Tree height vs width — Ex 3.2, 5.2.