BFS Breadth First Search on Graph in DSA Javascript - Time & Space Complexity
We want to understand how the time needed to explore a graph grows as the graph gets bigger using BFS.
How does BFS's work time change when the graph has more nodes and edges?
Analyze the time complexity of the following code snippet.
function bfs(graph, start) {
const visited = new Set();
const queue = [start];
visited.add(start);
while (queue.length > 0) {
const node = queue.shift();
for (const neighbor of graph[node]) {
if (!visited.has(neighbor)) {
visited.add(neighbor);
queue.push(neighbor);
}
}
}
}
This code explores all nodes reachable from the start node by visiting neighbors level by level.
- Primary operation: The while loop runs as long as there are nodes to visit, and inside it, the for loop visits all neighbors of the current node.
- How many times: Each node is visited once, and each edge is checked once during neighbor visits.
As the graph grows, BFS visits every node and edge once.
| Input Size (n nodes, m edges) | Approx. Operations |
|---|---|
| 10 nodes, 15 edges | About 10 node visits + 15 edge checks = 25 operations |
| 100 nodes, 200 edges | About 100 node visits + 200 edge checks = 300 operations |
| 1000 nodes, 3000 edges | About 1000 node visits + 3000 edge checks = 4000 operations |
Pattern observation: The total work grows roughly in proportion to the number of nodes plus edges.
Time Complexity: O(n + m)
This means BFS takes time proportional to the total nodes plus edges in the graph.
[X] Wrong: "BFS always takes O(n²) time because it has nested loops."
[OK] Correct: The inner loop only runs over neighbors, so total work over all nodes is proportional to edges, not nodes squared.
Knowing BFS time complexity helps you explain how graph searches scale and why BFS is efficient for many problems.
"What if the graph is represented as an adjacency matrix instead of adjacency lists? How would the time complexity change?"
Practice
Solution
Step 1: Understand BFS traversal method
BFS explores nodes level by level, so it needs to remember nodes in the order they are discovered.Step 2: Identify the data structure for order
A queue follows First-In-First-Out (FIFO), perfect for level order traversal in BFS.Final Answer:
A queue to explore nodes level by level -> Option CQuick Check:
BFS uses queue = A [OK]
- Confusing BFS with DFS and choosing stack
- Thinking BFS uses priority queue
- Ignoring the order of node visits
Solution
Step 1: Recall JavaScript array methods for queue
JavaScript arrays use `push()` to add elements at the end, simulating enqueue.Step 2: Verify other options
Methods like `enqueue()`, `add()`, or `insert()` are not standard array methods in JavaScript.Final Answer:
queue.push(v); -> Option AQuick Check:
Enqueue in JS array = push() [OK]
- Using non-existent enqueue() method
- Confusing push() with pop()
- Trying to use add() or insert() which don't exist
const graph = {
1: [2, 3],
2: [4],
3: [4],
4: []
};
function bfs(start) {
const queue = [start];
const visited = new Set([start]);
const order = [];
while(queue.length > 0) {
const node = queue.shift();
order.push(node);
for(const neighbor of graph[node]) {
if(!visited.has(neighbor)) {
visited.add(neighbor);
queue.push(neighbor);
}
}
}
return order;
}
console.log(bfs(1));
What will be the output printed?Solution
Step 1: Start BFS from node 1
Queue = [1], visited = {1}, order = []. Dequeue 1, order = [1]. Enqueue neighbors 2 and 3.Step 2: Visit nodes in queue order
Queue = [2,3]. Dequeue 2, order = [1,2]. Enqueue neighbor 4. Queue = [3,4]. Dequeue 3, order = [1,2,3]. Neighbor 4 already visited, skip. Dequeue 4, order = [1,2,3,4].Final Answer:
[1, 2, 3, 4] -> Option BQuick Check:
BFS order = [1, 2, 3, 4] [OK]
- Mixing order of neighbors
- Not marking visited before enqueue
- Using stack behavior instead of queue
function bfs(start, graph) {
const queue = [start];
const visited = new Set();
const order = [];
while(queue.length > 0) {
const node = queue.shift();
order.push(node);
for(const neighbor of graph[node]) {
if(!visited.has(neighbor)) {
queue.push(neighbor);
visited.add(neighbor);
}
}
}
return order;
}Solution
Step 1: Check order of visited marking
Visited nodes are marked after enqueueing neighbors, which can cause duplicates if neighbors appear multiple times.Step 2: Correct approach
Mark nodes as visited before enqueueing to avoid adding duplicates to the queue.Final Answer:
Visited nodes are not marked before enqueueing, causing duplicates -> Option AQuick Check:
Mark visited before enqueue = no duplicates [OK]
- Marking visited after enqueue
- Not marking visited at all
- Initializing queue incorrectly
Solution
Step 1: Understand BFS property for shortest path
BFS explores nodes level by level, so the first time we reach the target node is the shortest path.Step 2: Track distance during BFS
Maintain a distance map or array, updating distance when a node is first visited to record shortest path length.Final Answer:
Use BFS with a queue and track distance for each node when first visited -> Option DQuick Check:
BFS + distance tracking = shortest path [OK]
- Using DFS which may not find shortest path
- Not tracking visited nodes causing infinite loops
- Using stack instead of queue for BFS
Ready to prove it?
Pass the test and this pattern moves unknown
