Dataslope logoDataslope

Graph Traversal: BFS and DFS

Learn breadth-first search, depth-first search, components, cycle detection, topological sort, and grid traversal in C++

Graph traversal means systematically visiting vertices reachable from a starting point. The two core tools are breadth-first search (BFS) and depth-first search (DFS).

BFS explores level by level from a source. It uses a queue: push the source, pop the oldest vertex, then push each unvisited neighbor.

BFS(adj, src):
    mark src visited
    push src into queue
    while queue not empty:
        u = pop front
        visit u
        for each v in adj[u]:
            if v is unvisited:
                mark v visited
                push v

Because BFS visits by increasing number of edges, it finds shortest paths in unweighted graphs.

Code Block
C++ 20 (202002L)

DFS goes as deep as possible before backtracking. It can be written with recursion or with an explicit stack.

DFS(u):
    mark u visited
    visit u
    for each v in adj[u]:
        if v is unvisited:
            DFS(v)
Code Block
C++ 20 (202002L)

The iterative version uses a stack. Push neighbors in reverse order if you want the same order as recursive DFS on a normally ordered adjacency list.

Code Block
C++ 20 (202002L)

Visited is non-negotiable

Use vector<bool> or another visited structure before pushing or recursing into neighbors. Without it, cyclic graphs can loop forever.

Connected components

To count connected components in an undirected graph, start a BFS or DFS from every unvisited vertex. Each new start discovers one component.

Code Block
C++ 20 (202002L)

Cycle detection

For an undirected graph, DFS tracks the parent. Seeing a visited neighbor that is not the parent means a cycle exists.

Code Block
C++ 20 (202002L)

For a directed graph, use colors: white = unvisited, gray = currently in recursion stack, black = fully processed. Finding an edge to gray means a cycle.

Code Block
C++ 20 (202002L)

Topological sort

A topological ordering places every directed edge u -> v with u before v. It exists only for DAGs. DFS can produce it by pushing each vertex after all outgoing neighbors finish.

Code Block
C++ 20 (202002L)

Kahn's algorithm is the BFS-like alternative: compute in-degrees, repeatedly pop vertices with in-degree 0, and decrement their outgoing neighbors.

Shortest path in an unweighted graph

BFS can also record distance and parent arrays.

Code Block
C++ 20 (202002L)

Grids as graphs: flood fill and islands

A grid cell can be a vertex. Edges connect up, down, left, and right neighbors.

A number-of-islands solution starts BFS from every unvisited land cell and marks its whole component.

Code Block
C++ 20 (202002L)

Challenge: BFS from source

Challenge
C++ 20 (202002L)
BFS from source

Implement bfsOrder to return the BFS visit order starting at src.

Challenge: Number of connected components

Challenge
C++ 20 (202002L)
Number of connected components

Implement countComponents by starting a traversal from every unvisited vertex.

Challenge: Number of islands

Challenge
C++ 20 (202002L)
Number of islands

Implement numIslands. Mutating the grid to mark visited land is allowed.

Check your understanding

QuestionSelect one

Which data structure is the usual core of BFS?

Queue

Stack

Binary search tree

Heap

QuestionSelect one

Which mechanism naturally supports DFS?

Queue only

Recursion or an explicit stack

Priority queue only

Hash table only

QuestionSelect one

When does BFS find shortest paths from a source?

In every weighted graph

Only in complete graphs

In unweighted graphs, where every edge has equal cost

Only in directed acyclic graphs

On this page