Bird
Raised Fist0
DSA Javascriptprogramming

Connected Components Using BFS in DSA Javascript

Choose your learning style10 modes available
Mental Model
We find groups of nodes where each node can reach every other node in the same group by exploring neighbors step-by-step.
Analogy: Imagine a group of friends at a party where everyone in a group can talk to each other directly or through others. BFS is like starting from one friend and visiting all friends they can reach before moving to another group.
Graph:
0 -> 1
↑    ↓
2    3

Components:
[0,1,2] and [3]
Dry Run Walkthrough
Input: Graph with edges: 0-1, 1-2, 3 isolated; find connected components
Goal: Identify all connected groups of nodes using BFS
Step 1: Start BFS from node 0, mark 0 visited
Visited: {0}
Queue: [0]
Why: We begin exploring from node 0 to find its connected group
Step 2: Dequeue 0, enqueue neighbor 1, mark visited
Visited: {0,1}
Queue: [1]
Why: Neighbor of 0 is 1, so we add it to explore next
Step 3: Dequeue 1, enqueue neighbor 2 (0 visited), mark visited
Visited: {0,1,2}
Queue: [2]
Why: Neighbors of 1 are 0 (visited) and 2, so enqueue 2
Step 4: Dequeue 2, neighbors are 1 visited, no enqueue
Visited: {0,1,2}
Queue: []
Why: All connected nodes from 0 explored
Step 5: Move to next unvisited node 3, start BFS, mark visited
Visited: {0,1,2,3}
Queue: [3]
Why: Node 3 is isolated, forms its own component
Step 6: Dequeue 3, no neighbors to enqueue
Visited: {0,1,2,3}
Queue: []
Why: Finished exploring node 3's component
Result:
Components found: [[0,1,2], [3]]
Annotated Code
DSA Javascript
class Graph {
  constructor(vertices) {
    this.vertices = vertices;
    this.adjList = new Map();
    for (let i = 0; i < vertices; i++) {
      this.adjList.set(i, []);
    }
  }

  addEdge(v, w) {
    this.adjList.get(v).push(w);
    this.adjList.get(w).push(v);
  }

  bfs(start, visited) {
    const queue = [];
    const component = [];
    queue.push(start);
    visited[start] = true;

    while (queue.length > 0) {
      const node = queue.shift();
      component.push(node);

      for (const neighbor of this.adjList.get(node)) {
        if (!visited[neighbor]) {
          visited[neighbor] = true;
          queue.push(neighbor);
        }
      }
    }
    return component;
  }

  connectedComponents() {
    const visited = Array(this.vertices).fill(false);
    const components = [];

    for (let i = 0; i < this.vertices; i++) {
      if (!visited[i]) {
        const comp = this.bfs(i, visited);
        components.push(comp);
      }
    }
    return components;
  }
}

// Driver code
const g = new Graph(4);
g.addEdge(0, 1);
g.addEdge(1, 2);
// Node 3 is isolated

const components = g.connectedComponents();
for (const comp of components) {
  console.log(comp.join(' -> ') + ' -> null');
}
queue.push(start); visited[start] = true;
Initialize BFS from start node, mark visited
const node = queue.shift(); component.push(node);
Process current node and add to current component
for (const neighbor of this.adjList.get(node)) { if (!visited[neighbor]) { visited[neighbor] = true; queue.push(neighbor); } }
Add unvisited neighbors to queue and mark visited
for (let i = 0; i < this.vertices; i++) { if (!visited[i]) { const comp = this.bfs(i, visited); components.push(comp); } }
Run BFS for each unvisited node to find all components
OutputSuccess
0 -> 1 -> 2 -> null 3 -> null
Complexity Analysis
Time: O(V + E) because BFS visits every vertex and edge once
Space: O(V) for the visited array and queue storing nodes
vs Alternative: Compared to DFS, BFS has similar time and space but explores neighbors level by level
Edge Cases
Graph with no edges (all isolated nodes)
Each node forms its own component
DSA Javascript
if (!visited[i]) {
Graph with a single node
One component containing that single node
DSA Javascript
if (!visited[i]) {
Graph with all nodes connected
One component containing all nodes
DSA Javascript
if (!visited[i]) {
When to Use This Pattern
When you need to find groups of connected nodes in a graph, use BFS to explore each group fully before moving to the next.
Common Mistakes
Mistake: Not marking nodes as visited before enqueueing causes repeated visits and infinite loops
Fix: Mark nodes visited immediately when adding to the queue
Summary
Finds all groups of connected nodes in a graph using BFS.
Use when you want to identify separate connected parts in an undirected graph.
Start BFS from each unvisited node to discover its entire connected component.

Practice

(1/5)
1. What does the BFS algorithm help find in an undirected graph when used for connected components?
easy
A. All nodes reachable from a starting node forming one connected component
B. The shortest path between two nodes only
C. The maximum degree of any node in the graph
D. The total number of edges in the graph

Solution

  1. Step 1: Understand BFS purpose in connected components

    BFS explores all nodes reachable from a starting node, marking them as part of the same connected component.
  2. Step 2: Differentiate BFS from other graph properties

    BFS does not directly find shortest paths between arbitrary nodes, maximum degree, or edge count in this context.
  3. Final Answer:

    All nodes reachable from a starting node forming one connected component -> Option A
  4. Quick Check:

    BFS finds connected components = D [OK]
Hint: BFS visits all nodes connected to start node [OK]
Common Mistakes:
  • Confusing BFS with shortest path only
  • Thinking BFS counts edges or degrees
  • Mixing BFS with DFS concepts
2. Which of the following is the correct way to initialize a queue for BFS in JavaScript?
easy
A. const queue = new Set(); queue.add(startNode);
B. const queue = []; queue.push(startNode);
C. const queue = {}; queue.enqueue(startNode);
D. const queue = null; queue.push(startNode);

Solution

  1. Step 1: Identify correct queue initialization

    In JavaScript, a queue for BFS is commonly implemented using an array with push() to add elements.
  2. Step 2: Check other options for errors

    Set does not have push(), object {} has no enqueue method, and null cannot be used as a queue.
  3. Final Answer:

    const queue = []; queue.push(startNode); -> Option B
  4. Quick Check:

    Array with push() for queue = B [OK]
Hint: Use array with push/pop or shift for BFS queue [OK]
Common Mistakes:
  • Using Set instead of array for queue
  • Using object without queue methods
  • Initializing queue as null
3. What will be the output of the following code snippet that finds connected components using BFS?
const graph = {
  0: [1],
  1: [0, 2],
  2: [1],
  3: [4],
  4: [3]
};

function bfs(start, visited) {
  const queue = [start];
  visited[start] = true;
  const component = [];
  while (queue.length) {
    const node = queue.shift();
    component.push(node);
    for (const neighbor of graph[node]) {
      if (!visited[neighbor]) {
        visited[neighbor] = true;
        queue.push(neighbor);
      }
    }
  }
  return component;
}

const visited = {};
const components = [];
for (const node in graph) {
  if (!visited[node]) {
    components.push(bfs(node, visited));
  }
}
console.log(components);
medium
A. [[0,1,2],[3,4]]
B. [[0,1],[2,3,4]]
C. [[0,1,2,3,4]]
D. [[1,0,2],[4,3]]

Solution

  1. Step 1: Trace BFS from node 0

    BFS visits 0, then 1, then 2 forming component [0,1,2].
  2. Step 2: Trace BFS from node 3

    Next unvisited node is 3, BFS visits 3 and 4 forming component [3,4].
  3. Final Answer:

    [[0,1,2],[3,4]] -> Option A
  4. Quick Check:

    Two connected components found = A [OK]
Hint: BFS groups connected nodes in order visited [OK]
Common Mistakes:
  • Assuming all nodes in one component
  • Mixing order of nodes in components
  • Ignoring visited tracking
4. Identify the bug in this BFS connected components code snippet:
function bfs(start, visited, graph) {
  const queue = [start];
  visited[start] = true;
  const component = [];
  while (queue.length > 0) {
    const node = queue.pop();
    component.push(node);
    for (const neighbor of graph[node]) {
      if (!visited[neighbor]) {
        visited[neighbor] = true;
        queue.push(neighbor);
      }
    }
  }
  return component;
}
medium
A. For loop syntax is incorrect
B. Not marking start node as visited
C. Using queue.pop() instead of queue.shift() causes wrong BFS order
D. queue.push(neighbor) should be queue.unshift(neighbor)

Solution

  1. Step 1: Check queue operation for BFS

    BFS requires removing from front (queue.shift()), but code uses pop() which removes from end, making it DFS behavior.
  2. Step 2: Verify other parts

    Start node is marked visited, for loop syntax is correct, and push() is correct to add neighbors at end.
  3. Final Answer:

    Using queue.pop() instead of queue.shift() causes wrong BFS order -> Option C
  4. Quick Check:

    pop() breaks BFS order = A [OK]
Hint: Use shift() to dequeue in BFS, pop() is for DFS [OK]
Common Mistakes:
  • Confusing pop() with shift() in queue
  • Not marking visited nodes
  • Incorrect loop syntax
5. Given a graph represented as an adjacency list, how would you modify the BFS connected components algorithm to count the number of connected components without storing the nodes in each component?
hard
A. Use DFS instead of BFS to count components
B. Store all nodes in a global array and count unique nodes after BFS
C. Count edges visited during BFS to find components
D. Increment a counter each time BFS starts from an unvisited node, without collecting nodes

Solution

  1. Step 1: Understand BFS role in counting components

    Each BFS call from an unvisited node explores one connected component fully.
  2. Step 2: Modify BFS to count components

    Instead of storing nodes, just increment a counter when BFS starts from an unvisited node.
  3. Final Answer:

    Increment a counter each time BFS starts from an unvisited node, without collecting nodes -> Option D
  4. Quick Check:

    Count BFS starts = connected components [OK]
Hint: Count BFS calls from unvisited nodes for components [OK]
Common Mistakes:
  • Storing all nodes unnecessarily
  • Confusing edge count with component count
  • Switching BFS to DFS without reason
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard