Overview
Breadth-first search (BFS) explores a graph level by level. Starting from a source, it visits every neighbor at distance 1, then every node at distance 2, and so on, using a first-in-first-out queue.
Because it expands in order of distance, BFS finds the shortest path in an unweighted graph. It is the default choice for minimum steps, minimum moves, nearest exit, and spreading processes such as rotting oranges or network broadcasts.
Drop a stone and the ripple reaches everything 1 metre away before anything 2 metres away. BFS is that ripple moving through a graph.
When to use it
- Shortest path or fewest steps when every edge costs the same.
- Level-order traversal of trees.
- Multi-source spreading problems (start with all sources in the queue).
- Checking connectivity or bipartiteness.
Problem patterns it solves
Recognize it when: minimum steps, moves, or transformations where every move costs the same.
- 1091. Shortest Path in Binary Matrix
- 127. Word Ladder
- 752. Open the Lock
- 433. Minimum Genetic Mutation
Recognize it when: process a tree or graph one layer at a time: per level, right side, zigzag.
- 102. Binary Tree Level Order Traversal
- 199. Binary Tree Right Side View
- 103. Zigzag Level Order Traversal
- 111. Minimum Depth of Binary Tree
Recognize it when: several starting points spread at the same time; distance to the nearest source.
- 994. Rotting Oranges
- 542. 01 Matrix
- 286. Walls and Gates
- 1162. As Far from Land as Possible
Recognize it when: count or measure connected regions in a grid.
- 200. Number of Islands
- 733. Flood Fill
- 695. Max Area of Island
Recognize it when: prerequisites, build order, detect impossible ordering.
- 207. Course Schedule
- 210. Course Schedule II
Where it is used in real software
'2nd and 3rd degree connections' on LinkedIn is a BFS from your profile limited to depth 3.
Crawlers visit pages level by level from seed URLs so important, nearby pages are fetched before deep ones.
On grids where every step costs the same, BFS finds the fewest moves; A* extends it with a heuristic.
Cheney's copying collector traverses reachable objects breadth-first using the destination space as its queue.
Key terms
- Queue
- FIFO structure holding discovered nodes waiting to be processed.
- Visited set
- Nodes already discovered, preventing repeated processing and infinite loops.
- Level / distance
- Number of edges from the source.
- Parent map
- Records which node discovered each node, allowing path reconstruction.
How it works, step by step
- 1Seed the queue
Push the source, mark it visited, and set its distance to 0.
- 2Dequeue the front node
Process nodes in the order they were discovered.
- 3Discover neighbors
For each unvisited neighbor, mark it visited immediately, set distance = current + 1, record the parent, and enqueue it.
- 4Repeat until empty
When the queue empties, every reachable node has its shortest distance.
- 5Rebuild the path
Follow parent links from the destination back to the source, then reverse.
BFS from A
A: B, C | B: D | C: D, E | D: F | E: F
| Dequeued | New neighbors | Queue after | Distances |
|---|---|---|---|
| A | B, C | B, C | A0 B1 C1 |
| B | D | C, D | D2 |
| C | E (D seen) | D, E | E2 |
| D | F | E, F | F3 |
| E | - (F seen) | F | - |
| F | - | empty | done |
NOWDequeued: A | New neighbors: B, C | Queue after: B, C | Distances: A0 B1 C1
Visit order is A, B, C, D, E, F. The shortest path from A to F has 3 edges: A, B, D, F (following parents F to D to B to A).
Implementation
type Graph = Map<string, string[]>; function bfs(graph: Graph, source: string) { const distance = new Map<string, number>([[source, 0]]); const parent = new Map<string, string | null>([[source, null]]); const queue: string[] = [source]; let head = 0; // avoid O(n) Array.shift() while (head < queue.length) { const node = queue[head++]; for (const next of graph.get(node) ?? []) { if (distance.has(next)) continue; // already discovered distance.set(next, distance.get(node)! + 1); parent.set(next, node); queue.push(next); } } return { distance, parent };} function pathTo(parent: Map<string, string | null>, target: string): string[] { if (!parent.has(target)) return []; const path: string[] = []; for (let node: string | null = target; node !== null; node = parent.get(node)!) { path.push(node); } return path.reverse();}Complexity and performance
Every vertex is enqueued once and every edge is examined once (twice for undirected).
Queue, visited set, and distance map.
Each cell is a vertex with up to 4 edges.
Trade-offs
BFS guarantees shortest paths in unweighted graphs but can hold a whole level in memory. DFS uses memory proportional to depth and suits cycle detection, topological order, and exhaustive search.
BFS is wrong when edges have different costs. Use Dijkstra for non-negative weights, or 0-1 BFS with a deque when weights are only 0 or 1.
Variants and related techniques
Enqueue every source at distance 0. Used for rotting oranges, walls and gates, and distance to nearest zero.
Process queue.length nodes per iteration to handle one level at a time, useful for tree level-order and minimum-depth problems.
Search from both ends and stop when frontiers meet, reducing explored nodes dramatically in large graphs like word ladder.
Common mistakes
- Marking nodes visited when dequeued instead of enqueued.
Fix: Mark on enqueue; otherwise the same node can be queued many times.
- Using Array.shift() in JavaScript.
Fix: shift is O(n). Use a head index or a real deque.
- Using BFS for weighted shortest paths.
Fix: Switch to Dijkstra with a priority queue.
Interview questions
Why does BFS find shortest paths in unweighted graphs?
The queue processes nodes in non-decreasing distance order. The first time a node is discovered, it is through a shortest path, because every node at a smaller distance was processed earlier.
How do you find the path, not just the distance?
Record parent[next] = node when discovering a node, then walk parents from the target back to the source.
Practice problems
| Problem | Difficulty | What it trains |
|---|---|---|
| Binary Tree Level Order Traversal | Medium | Level-by-level BFS. |
| Number of Islands | Medium | BFS flood fill on a grid. |
| Rotting Oranges | Medium | Multi-source BFS with time levels. |
| Shortest Path in Binary Matrix | Medium | 8-direction grid BFS. |
| Open the Lock | Medium | BFS over generated states. |
| Word Ladder | Hard | Implicit graph and bidirectional BFS. |