A graph consists of vertices (nodes) connected by edges. Graphs can be directed or undirected, weighted or unweighted. Graph traversal algorithms visit every vertex systematically. The two fundamental approaches are BFS (Breadth-First Search) and DFS (Depth-First Search).
Example graph (undirected) used throughout this lesson:
A - B - D | | C - E
Adjacency list: A:[B,C], B:[A,D,E], C:[A,E], D:[B], E:[B,C]
BFS explores a graph level by level — first all neighbours of the start node, then their neighbours, and so on. It uses a FIFO queue and a visited set to avoid revisiting nodes.
function BFS(graph, start)
queue ← [start]
visited ← {start}
order ← []
while queue is not empty
node ← dequeue(queue) // take from front (FIFO)
order.append(node)
for neighbour in graph[node]
if neighbour not in visited then
visited.add(neighbour)
enqueue(queue, neighbour)
endif
next neighbour
endwhile
return order
endfunction
| Step | Queue (front→rear) | Visited | Process |
|---|---|---|---|
| Start | [A] | {A} | Initialise |
| 1 | [B, C] | {A,B,C} | Dequeue A; enqueue B, C |
| 2 | [C, D, E] | {A,B,C,D,E} | Dequeue B; enqueue D, E (A already visited) |
| 3 | [D, E] | {A,B,C,D,E} | Dequeue C; E already visited; no new nodes |
| 4 | [E] | {A,B,C,D,E} | Dequeue D; B already visited |
| 5 | [] | {A,B,C,D,E} | Dequeue E; all neighbours visited |
BFS order: A → B → C → D → E
Complexity: O(V + E) where V = vertices, E = edges. Every vertex and edge is processed exactly once.
DFS explores a graph by going as deep as possible along each branch before backtracking. It uses a LIFO stack (or the call stack for recursion) and a visited set.
function DFS_iterative(graph, start)
stack ← [start]
visited ← {}
order ← []
while stack is not empty
node ← pop(stack) // take from top (LIFO)
if node not in visited then
visited.add(node)
order.append(node)
for neighbour in graph[node]
if neighbour not in visited then
push(stack, neighbour)
endif
next neighbour
endif
endwhile
return order
endfunction
function DFS_recursive(graph, node, visited)
if visited is None then visited ← {}
visited.add(node)
process(node)
for neighbour in graph[node]
if neighbour not in visited then
DFS_recursive(graph, neighbour, visited)
endif
next neighbour
endfunction
| Step | Stack (top→) | Visited | Process |
|---|---|---|---|
| Start | [A] | {} | Initialise |
| 1 | [B, C] | {A} | Pop A; visit A; push B, C |
| 2 | [B, A, D, E] | {A,C} | Pop C; visit C; push A, E (top→E) |
| 3 | [B, A, D, B, C] | {A,C,E} | Pop E; visit E; push B, C |
| 4 | [B, A, D, B] | {A,C,E} | Pop C — already visited, skip |
| 5 | [B, A, D] | {A,B,C,E} | Pop B; visit B; push A,D,E |
| 6 | [B, A] | {A,B,C,D,E} | Pop D; visit D |
| 7- | [] | {A,B,C,D,E} | Pop remaining — all visited |
DFS order (one possible): A → C → E → B → D (order depends on neighbour ordering)
Complexity: O(V + E) — same as BFS. Every vertex and edge is processed exactly once.
| Feature | BFS | DFS |
|---|---|---|
| Data structure | Queue (FIFO) | Stack (LIFO) or recursion |
| Exploration order | Level by level (breadth-first) | As deep as possible first |
| Finds shortest path? | Yes (unweighted graphs) | No — not guaranteed |
| Time complexity | O(V + E) | O(V + E) |
| Space complexity | O(V) — queue can hold entire level | O(V) — stack/call stack depth |
| Memory usage | Higher (wide graphs) | Lower (deep graphs) |
| Use for | Shortest path, level-order, social graphs | Topological sort, cycle detection, mazes |
8 questions · 24 marks · instantly marked
| Term | Definition |
|---|