Easy Tutorial
❮ Union Find Quick Merge Graph Theory Deep ❯

Breadth-First Search and Shortest Path

Breadth-First Search (BFS) starts from a vertex v, visits this node, and marks it as visited. Then, it sequentially visits all unvisited adjacent nodes {vi,...,vj} of v, marks them as visited, and repeats the process for each node in {vi,...,vj}, until all nodes have been visited.

The process can be divided into three steps:

The diagram below shows the traversal order starting from 0 in blue on the right, and the distances from 0 recorded below. It demonstrates that BFS can find the shortest path in an unweighted graph.

The following code demonstrates how to perform a breadth-first traversal and find the shortest path. We add a global variable ord array to record the order of nodes in the path. ord[i] represents the order of node i in the path. The constructor is adjusted accordingly, recording the distance with ord[i] = ord[v] + 1 for each unvisited node visited. The time complexity for BFS with an adjacency list is O(V+E), and for an adjacency matrix, it is O(V^2).

...
// Constructor, pathfinding algorithm, finds paths from point s to other points in graph
public ShortestPath(Graph graph, int s){
    // Algorithm initialization
    G = graph;
    assert s >= 0 && s < G.V();

    visited = new boolean[G.V()];
    from = new int[G.V()];
    ord = new int[G.V()];
    for( int i = 0 ; i < G.V() ; i ++ ){
        visited[i] = false;
        from[i] = -1;
        ord[i] = -1;
    }
    this.s = s;
    // Unweighted graph shortest path algorithm, BFS traversal starting from s
    LinkedList<Integer> q = new LinkedList<Integer>();
    q.push( s );
    visited[s] = true;
    ord[s] = 0;
    while( !q.isEmpty() ){
        int v = q.pop();
        for( int i : G.adj(v) )
            if( !visited[i] ){
                q.push(i);
                visited[i] = true;
                from[i] = v;
                ord[i] = ord[v] + 1;
            }
    }
}
...

To check the shortest path length from point s to point w, if s is not reachable to w, return -1.

...
public int length(int w){
    assert w >= 0 && w < G.V();
    return ord[w];
}
...

Java Example Code

Source Code Download: Download

src/tutorialpro/graph/ShortestPath.java File Code:

package tutorialpro.graph;

import tutorialpro.graph.read.Graph;

import java.util.LinkedList;
import java.util.Stack;
import java.util.Vector;

/**
 * Breadth-First Search and Shortest Path
 */
public class ShortestPath {
    // Graph reference
    private Graph G;
    // Starting point
    private int s;
    // Record if nodes are visited during DFS
    private boolean[] visited;
    // Record path, from[i] indicates the previous node of i on the search path
    private int[] from;
    // Record the order of nodes in the path. ord[i] indicates the order of node i in the path.
private int[] ord;
// Constructor, pathfinding algorithm, finds paths from source s to other nodes in graph
public ShortestPath(Graph graph, int s) {

    // Algorithm initialization
    G = graph;
    assert s >= 0 && s < G.V();

    visited = new boolean[G.V()];
    from = new int[G.V()];
    ord = new int[G.V()];
    for (int i = 0; i < G.V(); i++) {
        visited[i] = false;
        from[i] = -1;
        ord[i] = -1;
    }
    this.s = s;
    // Undirected graph shortest path algorithm, starting from s and performing a breadth-first traversal of the entire graph
    LinkedList<Integer> q = new LinkedList<Integer>();
    q.push(s);
    visited[s] = true;
    ord[s] = 0;
    while (!q.isEmpty()) {
        int v = q.pop();
        for (int i : G.adj(v))
            if (!visited[i]) {
                q.push(i);
                visited[i] = true;
                from[i] = v;
                ord[i] = ord[v] + 1;
            }
    }
}

// Checks if there is a path from s to w
public boolean hasPath(int w) {
    assert w >= 0 && w < G.V();
    return visited[w];
}
// Retrieves the path from s to w and stores it in vec
public Vector<Integer> path(int w) {
    assert hasPath(w);
    Stack<Integer> s = new Stack<Integer>();
    // Reverse lookup of the path from s to w using the from array, stored in a stack
    int p = w;
    while (p != -1) {
        s.push(p);
        p = from[p];
    }

    // Retrieve elements from the stack to get the ordered path from s to w
    Vector<Integer> res = new Vector<Integer>();
    while (!s.empty())
        res.add(s.pop());

    return res;
}

// Prints the path from s to w
public void showPath(int w) {
    assert hasPath(w);
    Vector<Integer> vec = path(w);
    for (int i = 0; i < vec.size(); i++) {
        System.out.print(vec.elementAt(i));
        if (i == vec.size() - 1)
            System.out.println();
        else
            System.out.print(" -> ");
    }
}
// Retrieves the shortest path length from s to w
// Returns -1 if s to w is not reachable
public int length(int w) {
    assert w >= 0 && w < G.V();
    return ord[w];
}
❮ Union Find Quick Merge Graph Theory Deep ❯