/****************************************************************************** * Compilation: javac DepthFirstPaths.java * Execution: java DepthFirstPaths G s * Dependencies: Graph.java Stack.java StdOut.java * Data files: https://algs4.cs.princeton.edu/41graph/tinyCG.txt * https://algs4.cs.princeton.edu/41graph/tinyG.txt * https://algs4.cs.princeton.edu/41graph/mediumG.txt * https://algs4.cs.princeton.edu/41graph/largeG.txt * * Run depth-first search on an undirected graph. * * % java Graph tinyCG.txt * 6 8 * 0: 2 1 5 * 1: 0 2 * 2: 0 1 3 4 * 3: 5 4 2 * 4: 3 2 * 5: 3 0 * * % java DepthFirstPaths tinyCG.txt 0 * 0 to 0: 0 * 0 to 1: 0-2-1 * 0 to 2: 0-2 * 0 to 3: 0-2-3 * 0 to 4: 0-2-3-4 * 0 to 5: 0-2-3-5 * ******************************************************************************/ /** * The {@code DepthFirstPaths} class represents a data type for finding * paths from a source vertex s to every other vertex * in an undirected graph. *
* This implementation uses depth-first search. * The constructor takes Θ(V + E) time in the * worst case, where V is the number of vertices and * E is the number of edges. * Each instance method takes Θ(1) time. * It uses Θ(V) extra space (not including the graph). *
* For additional documentation, see
* Section 4.1
* of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class DepthFirstPaths {
private boolean[] marked; // marked[v] = is there an s-v path?
private int[] edgeTo; // edgeTo[v] = last edge on s-v path
private final int s; // source vertex
/**
* Computes a path between {@code s} and every other vertex in graph {@code G}.
* @param G the graph
* @param s the source vertex
* @throws IllegalArgumentException unless {@code 0 <= s < V}
*/
public DepthFirstPaths(Graph G, int s) {
this.s = s;
edgeTo = new int[G.V()];
marked = new boolean[G.V()];
validateVertex(s);
dfs(G, s);
}
// depth first search from v
private void dfs(Graph G, int v) {
marked[v] = true;
for (int w : G.adj(v)) {
if (!marked[w]) {
edgeTo[w] = v;
dfs(G, w);
}
}
}
/**
* Is there a path between the source vertex {@code s} and vertex {@code v}?
* @param v the vertex
* @return {@code true} if there is a path, {@code false} otherwise
* @throws IllegalArgumentException unless {@code 0 <= v < V}
*/
public boolean hasPathTo(int v) {
validateVertex(v);
return marked[v];
}
/**
* Returns a path between the source vertex {@code s} and vertex {@code v}, or
* {@code null} if no such path.
* @param v the vertex
* @return the sequence of vertices on a path between the source vertex
* {@code s} and vertex {@code v}, as an Iterable
* @throws IllegalArgumentException unless {@code 0 <= v < V}
*/
public Iterable