Graphs, BFS and DFS

Represent networks with adjacency lists and matrices, and explore them breadth-first and depth-first.

A graph G = (V, E) is a set of vertices (nodes) V connected by edges E. Roads between cities, friendships, web links and course prerequisites are all graphs.

  • Undirected: an edge {u, v} can be travelled both ways. Directed: an edge (u, v) goes from u to v only.
  • Weighted: each edge has a cost, such as a distance.
  • The degree of a vertex is its number of edges (in a directed graph: in-degree and out-degree).
  • A graph is connected if every vertex can reach every other vertex.
ABDEFC
The undirected graph used in this lesson

Representations

Adjacency matrixAdjacency list
IdeaV × V table, cell [u][v] = 1 if there is an edgefor each vertex, a list of its neighbours
SpaceΘ(V²)Θ(V + E)
Is (u, v) an edge?O(1)O(degree of u)
Visit all neighbours of uΘ(V)Θ(degree of u)
Best fordense graphssparse graphs (most real graphs)

In an undirected graph the sum of all degrees is 2E, because each edge adds 1 to the degree of both its ends (the handshaking lemma).

Breadth-first search (BFS)

BFS explores the graph in layers: first the start vertex, then all its neighbours, then their unvisited neighbours, and so on. It uses a queue. In an unweighted graph, BFS finds the shortest path (fewest edges) from the start to every vertex.

Depth-first search (DFS)

DFS goes as deep as possible along one path before backtracking. It uses a stack, usually the call stack through recursion. DFS is the basis for detecting cycles, topological sorting and finding connected components.

Both run in O(V + E) time with an adjacency list.

import java.util.*;

public class Main {
    static Map<String, List<String>> graph = new LinkedHashMap<>();

    static void addEdge(String u, String v) {
        graph.computeIfAbsent(u, k -> new ArrayList<>()).add(v);
        graph.computeIfAbsent(v, k -> new ArrayList<>()).add(u);
    }

    static Map<String, Integer> bfs(String start) {
        Map<String, Integer> dist = new LinkedHashMap<>();
        Queue<String> q = new ArrayDeque<>();
        dist.put(start, 0);
        q.add(start);
        while (!q.isEmpty()) {
            String u = q.poll();
            for (String v : graph.get(u)) {
                if (!dist.containsKey(v)) {          // first time we see v
                    dist.put(v, dist.get(u) + 1);
                    q.add(v);
                }
            }
        }
        return dist;
    }

    static void dfs(String u, Set<String> seen, List<String> order) {
        seen.add(u);
        order.add(u);
        for (String v : graph.get(u)) {
            if (!seen.contains(v)) dfs(v, seen, order);
        }
    }

    public static void main(String[] args) {
        String[][] edges = {{"A", "B"}, {"A", "C"}, {"B", "D"}, {"C", "D"}, {"D", "E"}, {"E", "F"}};
        for (String[] e : edges) addEdge(e[0], e[1]);

        System.out.println("adjacency list: " + graph);
        Map<String, Integer> dist = bfs("A");
        System.out.println("BFS order:      " + String.join(" ", dist.keySet()));
        System.out.println("BFS distances:  " + dist);
        List<String> order = new ArrayList<>();
        dfs("A", new HashSet<>(), order);
        System.out.println("DFS order:      " + String.join(" ", order));
    }
}
Output
adjacency list: {A=[B, C], B=[A, D], C=[A, D], D=[B, C, E], E=[D, F], F=[E]}
BFS order:      A B C D E F
BFS distances:  {A=0, B=1, C=1, D=2, E=3, F=4}
DFS order:      A B D C E F

The order in which neighbours are stored decides which of several valid BFS or DFS orders you get.

Topological sort

A topological order of a directed acyclic graph (DAG) lists the vertices so that every edge goes from earlier to later, like an order to take courses so that prerequisites come first. Kahn's algorithm repeatedly removes a vertex with in-degree 0.

MathsAlgoDSProgDB
Course prerequisites as a directed acyclic graph
import java.util.*;

public class Main {
    public static void main(String[] args) {
        String[][] edges = {{"Maths", "DS"}, {"Prog", "DS"}, {"DS", "Algo"}, {"Prog", "DB"}, {"Maths", "Algo"}};
        Map<String, List<String>> out = new TreeMap<>();
        Map<String, Integer> indeg = new TreeMap<>();
        for (String[] e : edges) {
            out.computeIfAbsent(e[0], k -> new ArrayList<>()).add(e[1]);
            out.computeIfAbsent(e[1], k -> new ArrayList<>());
            indeg.merge(e[1], 1, Integer::sum);
            indeg.putIfAbsent(e[0], 0);
        }
        PriorityQueue<String> ready = new PriorityQueue<>();     // alphabetical among the ready ones
        indeg.forEach((v, d) -> { if (d == 0) ready.add(v); });
        List<String> order = new ArrayList<>();
        while (!ready.isEmpty()) {
            String u = ready.poll();
            order.add(u);
            for (String v : out.get(u)) if (indeg.merge(v, -1, Integer::sum) == 0) ready.add(v);
        }
        System.out.println(String.join(" -> ", order));
    }
}
Output
Maths -> Prog -> DB -> DS -> Algo

If the loop ends before every vertex is output, the graph has a cycle and no topological order exists.

GATE-style practice questions

GATE-styleNAT · numerical answer

An undirected graph has 10 vertices and every vertex has degree 3. How many edges does it have?

Show answer and explanationAnswer: 15

By the handshaking lemma, the sum of degrees is 2E, so 10 × 3 = 2E and E = 15.

GATE-styleNAT · numerical answer

BFS is run from vertex A on the graph shown at the top of this lesson (neighbours visited in alphabetical order). What is the BFS distance from A to F?

Show answer and explanationAnswer: 4

The layers are {A}, {B, C}, {D}, {E}, {F}, so F is 4 edges away (for example A → B → D → E → F).

GATE-styleMSQ · one or more correct answers

Which statements are true for a graph with V vertices and E edges? (Select all that apply.)

Show answer and explanationAnswer: A, B, D

BFS, not DFS, finds shortest paths in unweighted graphs, because it explores vertices in order of distance. The other statements are standard facts.

GATE-styleNAT · numerical answer

How many different topological orderings does the DAG with edges a → b, a → c, b → d, c → d have?

Show answer and explanationAnswer: 2

a must come first and d last. b and c can appear in either order, so the orderings are a b c d and a c b d.