Undirected Graphs - DFS
- Mimic maze exploration
- Find all vertical connected to a given source vertex
- Find a path between two vertices
API
public interface Paths
{
boolean hasPathTo(int v);
Iterable<Integer> pathTo(int v);
}
Implementation
DFS(to visit a vertex v)
{
Mark v as visted.
Recursively visit all unmarked vertices w adjacent to v.
}
public class DepthFirstSearch implements Paths
{
private boolean[] marked;
private int[] edgeTo;
private int s;
public DepthFirstSearch(Graph G, int s)
{
dfs(G, s);
}
private void dfs(Graph G, int v)
{
marked[v] = true;
for(int w: G.adj(v))
{
if(!marked[w])
{
dfs(G, w);
edgeTo[w] = v;
}
}
}
public boolean hasPathTo(int v)
{
return marked[v];
}
public Iterable<Integer> pathTo(int v)
{
if(!hasPathTo)
return null;
Stack<Integer> path = new Stack<Integer>();
for(int x = v; x != s; x = edgeTo[x])
{
path.push(x);
}
path.push(s);
return path;
}
}
Application: Connectivity Queries
- Connected component: A maximal set of connected vertices.
API
public interface CC
{
boolean connect(int v, int w);
int count();
int id(int v);
}
Implementation
Connected components
{
Initilize all vertices v as unmarked.
For each unmared vertex v, run DFS to identify all vertices discovered as part of the same component.
}
public class CCImpl implements CC
{
private boolean marked[];
private int[] id;
private int count;
public CCImpl(Graph G)
{
marked = new boolean[G.V()];
id = new int[G.V()];
for(int v = 0; v < G.V(); v++)
{
if(!marked[v])
{
dfs(G, v);
count ++;
}
}
}
private dfs(Graph G, int v)
{
marked[v] = true;
id[v] = count;
for (int w: G.adj(v))
if(!marked[w])
dfs(G, w);
}
public int count()
{
return count;
}
public int id(int v)
{
return id[v];
}
}