Breadth-first search (BFS) using a queue
BFS explores a graph level by level: visit the start vertex, then all neighbors, then their unvisited neighbors, and so on. A queue (FIFO) holds the frontier of vertices waiting to be processed. A visited array prevents re-enqueueing.
- Idea — FIFO frontier
- Algorithm steps
- Example in C — adjacency list, fixed small graph
- Complexity — O(V + E)
1) Why a queue?
Vertices discovered earlier must be processed before those discovered later. That is exactly FIFO behavior. DFS uses a stack (or recursion) instead.
2) BFS outline
| Step | Action |
|---|---|
| 1 | Mark start visited; enqueue start. |
| 2 | While queue not empty: dequeue u. |
| 3 | For each neighbor v of u: if not visited, mark visited and enqueue v. |
3) Example in C
Undirected graph with 5 vertices (0–4). Edges: 0–1, 0–2, 1–3, 2–4 (adjacency lists below).
#include <stdio.h>
#include <string.h>
#define V 5
#define MAXE 16
static int adj[V][MAXE];
static int deg[V];
static void add_edge(int a, int b) {
adj[a][deg[a]++] = b;
adj[b][deg[b]++] = a;
}
int main(void) {
int q[V * V], front = 0, rear = 0;
int vis[V];
memset(vis, 0, sizeof vis);
add_edge(0, 1);
add_edge(0, 2);
add_edge(1, 3);
add_edge(2, 4);
int start = 0;
vis[start] = 1;
q[rear++] = start;
printf("BFS order: ");
while (front < rear) {
int u = q[front++];
printf("%d ", u);
for (int i = 0; i < deg[u]; i++) {
int v = adj[u][i];
if (!vis[v]) {
vis[v] = 1;
q[rear++] = v;
}
}
}
printf("\n");
return 0;
}
Graph structure
| Edge Added | Resulting Connections |
|---|---|
add_edge(0, 1) | 0-1 |
add_edge(0, 2) | 0-2 |
add_edge(1, 3) | 1-3 |
add_edge(2, 4) | 2-4 |
Visual graph
3
|
1
|
0 --- 2 --- 4
| Vertex | deg[] | Adjacent Vertices (adj[vertex]) |
|---|---|---|
| 0 | 2 | [1, 2] |
| 1 | 2 | [0, 3] |
| 2 | 2 | [0, 4] |
| 3 | 1 | [1] |
| 4 | 1 | [2] |
BFS traversal step-by-step
| Step | front | rear | Dequeue (u) | Queue Contents (front->rear) | vis[] Array (visited vertices) | Process Neighbors (v) | New Enqueues |
|---|---|---|---|---|---|---|---|
| Start | 0 | 1 | - | [0] | {0} | - | - |
| 1 | 0->1 | 1 | 0 | [] | {0} | neighbors: 1, 2 | enqueue 1, 2 |
| 2 | 1 | 1->3 | - | [1, 2] | {0, 1, 2} | - | - |
| 3 | 1->2 | 3 | 1 | [2] | {0, 1, 2} | neighbors: 0, 3 | enqueue 3 |
| 4 | 2 | 3->4 | - | [2, 3] | {0, 1, 2, 3} | - | - |
| 5 | 2->3 | 4 | 2 | [3] | {0, 1, 2, 3} | neighbors: 0, 4 | enqueue 4 |
| 6 | 3 | 4->5 | - | [3, 4] | {0, 1, 2, 3, 4} | - | - |
| 7 | 3->4 | 5 | 3 | [4] | {0, 1, 2, 3, 4} | neighbors: 1 (already visited) | none |
| 8 | 4->5 | 5 | 4 | [] | {0, 1, 2, 3, 4} | neighbors: 2 (already visited) | none |
| 9 | 5 | 5 | (loop ends) | - | - | - | - |
BFS order output
| Print Order | Vertex Printed | When Printed |
|---|---|---|
| 1st | 0 | After dequeue #1 |
| 2nd | 1 | After dequeue #3 |
| 3rd | 2 | After dequeue #5 |
| 4th | 3 | After dequeue #7 |
| 5th | 4 | After dequeue #8 |
Final output
BFS order: 0 1 2 3 4
Key observations
| Aspect | Explanation |
|---|---|
| BFS Property | Explores vertices in levels (distance from start). |
| Level 0 | {0} |
| Level 1 | {1, 2} |
| Level 2 | {3, 4} |
| Queue Type | Simple array-based queue (not circular, sufficient size). |
| Queue Size | V * V = 25 (enough for worst-case BFS in this tutorial). |
| Visited Check | Prevents re-enqueueing and infinite loops. |
| Time Complexity | O(V + E) = O(5 + 4) = O(9) operations (conceptual count). |
| Space Complexity | O(V) = O(5) for queue and visited array (algorithmic bound). |
Important note: The graph is not disconnected; all vertices are reachable from start vertex 0 via paths through 1 and 2.
Execution summary
| Dequeue order | Output | Newly enqueued |
|---|---|---|
| Start | — | Enqueue 0 |
| 1 | 0 | 1, 2 |
| 2 | 1 | 3 |
| 3 | 2 | 4 |
| 4–5 | 3, 4 | (none) |
Printed line: BFS order: 0 1 2 3 4 (neighbor order follows how edges were stored in each adjacency list).
4) Complexity
- Time: each vertex dequeued once, each edge examined twice in undirected graph → O(V + E).
- Space:
visitedO(V), queue O(V) in worst case — see space complexity.
Key takeaway
BFS = queue + visited. Same pattern extends to level-order on trees and shortest paths in unweighted graphs.
Next up: Level-order traversal · Shortest path (unweighted) · All queue topics