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.

On this page
  • 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

Logical steps
StepAction
1Mark start visited; enqueue start.
2While queue not empty: dequeue u.
3For 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

Edges added in the program
Edge AddedResulting 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
Adjacency list after all edges
Vertexdeg[]Adjacent Vertices (adj[vertex])
02[1, 2]
12[0, 3]
22[0, 4]
31[1]
41[2]

BFS traversal step-by-step

Queue and visited array evolution
Step front rear Dequeue (u) Queue Contents (front->rear) vis[] Array (visited vertices) Process Neighbors (v) New Enqueues
Start01-[0]{0}--
10->110[]{0}neighbors: 1, 2enqueue 1, 2
211->3-[1, 2]{0, 1, 2}--
31->231[2]{0, 1, 2}neighbors: 0, 3enqueue 3
423->4-[2, 3]{0, 1, 2, 3}--
52->342[3]{0, 1, 2, 3}neighbors: 0, 4enqueue 4
634->5-[3, 4]{0, 1, 2, 3, 4}--
73->453[4]{0, 1, 2, 3, 4}neighbors: 1 (already visited)none
84->554[]{0, 1, 2, 3, 4}neighbors: 2 (already visited)none
955(loop ends)----

BFS order output

Print sequence
Print OrderVertex PrintedWhen Printed
1st0After dequeue #1
2nd1After dequeue #3
3rd2After dequeue #5
4th3After dequeue #7
5th4After dequeue #8

Final output

BFS order: 0 1 2 3 4

Key observations

Important BFS points from this run
AspectExplanation
BFS PropertyExplores vertices in levels (distance from start).
Level 0{0}
Level 1{1, 2}
Level 2{3, 4}
Queue TypeSimple array-based queue (not circular, sufficient size).
Queue SizeV * V = 25 (enough for worst-case BFS in this tutorial).
Visited CheckPrevents re-enqueueing and infinite loops.
Time ComplexityO(V + E) = O(5 + 4) = O(9) operations (conceptual count).
Space ComplexityO(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

Traversal from vertex 0
Dequeue orderOutputNewly enqueued
StartEnqueue 0
101, 2
213
324
4–53, 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: visited O(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