Breadth-First Search (BFS)

November 19, 2025
#bfs #breadth-first-search #graph-traversal #algorithms #graph #interviewing

Introduction

Breadth-First Search (BFS) is a fundamental graph traversal algorithm that explores vertices level by level, visiting all neighbors of a vertex before moving to the next level. Think of it like ripples spreading out in water—you explore all vertices at distance 1, then distance 2, and so on.

BFS is essential for finding shortest paths in unweighted graphs, level-order traversal of trees, and solving maze/puzzle problems. It uses a queue to maintain the order of exploration.

Review Graphs, Queues, and Binary Trees first if needed.

How BFS works

BFS explores a graph in layers:

  1. Start at a source vertex
  2. Visit all neighbors (distance 1)
  3. Visit all neighbors of neighbors (distance 2)
  4. Continue until all reachable vertices are visited

Visual example:

Graph:
    A --- B --- C
    |     |
    D --- E

BFS from A:
Level 0: A
Level 1: B, D (neighbors of A)
Level 2: C, E (neighbors of B and D)

Order: A, B, D, C, E

BFS algorithm

Key components:

  • Queue: Maintains vertices to visit (FIFO)
  • Visited set: Tracks visited vertices to avoid cycles
  • Level tracking (optional): Track distance from source

Steps:

  1. Enqueue starting vertex and mark as visited
  2. While queue is not empty:
    • Dequeue a vertex
    • Process it
    • Enqueue all unvisited neighbors
    • Mark neighbors as visited

BFS implementation

BFS on a graph

BFS on a binary tree

Finding shortest path with BFS

Common BFS problems

1. Number of islands (2D grid)

function numIslands(grid) {
  if (!grid || grid.length === 0) return 0;

  const rows = grid.length;
  const cols = grid[0].length;
  let count = 0;

  function bfs(r, c) {
    const queue = [[r, c]];
    grid[r][c] = '0'; // Mark as visited

    const directions = [[0,1], [1,0], [0,-1], [-1,0]];

    while (queue.length > 0) {
      const [row, col] = queue.shift();

      for (const [dr, dc] of directions) {
        const newRow = row + dr;
        const newCol = col + dc;

        if (newRow >= 0 && newRow < rows &&
            newCol >= 0 && newCol < cols &&
            grid[newRow][newCol] === '1') {
          grid[newRow][newCol] = '0';
          queue.push([newRow, newCol]);
        }
      }
    }
  }

  for (let r = 0; r < rows; r++) {
    for (let c = 0; c < cols; c++) {
      if (grid[r][c] === '1') {
        bfs(r, c);
        count++;
      }
    }
  }

  return count;
}

2. Word ladder (shortest transformation)

function ladderLength(beginWord, endWord, wordList) {
  const wordSet = new Set(wordList);
  if (!wordSet.has(endWord)) return 0;

  const queue = [[beginWord, 1]]; // [word, level]
  const visited = new Set([beginWord]);

  while (queue.length > 0) {
    const [word, level] = queue.shift();

    if (word === endWord) return level;

    // Try changing each character
    for (let i = 0; i < word.length; i++) {
      for (let c = 97; c <= 122; c++) { // 'a' to 'z'
        const newWord = word.slice(0, i) +
                       String.fromCharCode(c) +
                       word.slice(i + 1);

        if (wordSet.has(newWord) && !visited.has(newWord)) {
          visited.add(newWord);
          queue.push([newWord, level + 1]);
        }
      }
    }
  }

  return 0; // No path
}

BFS vs DFS comparison

Feature BFS DFS
Data structure Queue (FIFO) Stack/Recursion (LIFO)
Order Level by level Depth first
Shortest path ✅ Yes (unweighted) ❌ No
Space O(width) O(height)
Use cases Shortest path, level-order Detect cycles, topological sort

Complexity analysis

  • Time: O(V + E) where V = vertices, E = edges
  • Space: O(V) for queue and visited set

Common pitfalls

  • Not marking as visited: Leads to infinite loops
  • Marking too late: Mark when adding to queue, not when dequeuing
  • Forgetting disconnected components: May need to run BFS from multiple starting points
  • Using DFS when BFS needed: BFS guarantees shortest path in unweighted graphs

When to use BFS

  • Finding shortest path in unweighted graphs
  • Level-order traversal of trees
  • Finding all nodes at distance k
  • Connected components in undirected graphs
  • Solving maze or grid problems
  • Peer-to-peer networks (broadcasting)

Practice problems

  1. Binary tree level order traversal
  2. Binary tree right side view
  3. Binary tree zigzag level order traversal
  4. Rotting oranges (grid BFS)
  5. Shortest path in binary matrix
  6. Word ladder
  7. Open the lock (BFS with states)
  8. Minimum knight moves
  9. Shortest bridge
  10. 01 Matrix (distance to nearest 0)
  11. Walls and gates
  12. Snakes and ladders
  13. Shortest path visiting all nodes
  14. Bus routes
  15. Minimum genetic mutation

Complexity summary

  • Time: O(V + E) — visit each vertex and edge once
  • Space: O(V) — queue and visited set

BFS is essential for graph traversal and guarantees the shortest path in unweighted graphs. Master BFS and you’ll be able to solve a wide range of graph and tree problems efficiently.

Thanks for visiting
We are actively updating content to this site. Thanks for visiting! Please bookmark this page and visit again soon.
Sponsor