Depth First Search - kgleong/software-engineering GitHub Wiki
Use DFS to return a path (if one exists) from one vertex to another.
List<Vertex> DFS(Vertex vertex,
Vertex vertexToFind,
List<Vertex> path,
Set<Vertex> visitedVertexList) {
List<Vertex> pathToEnd = null;
if(vertex == vertexToFind) {
pathToEnd = path;
pathToEnd.add(vertexToFind);
}
else if(vertex != null) {
for(Vertex neighbor : vertex.adjacencyList) {
if(!vistedVertexList.contains(neighbor)) {
vistedVertexList.add(neighbor);
List<Vertex> pathIncludingNeighbor = new ArrayList<>(path);
pathIncludingNeighbor.add(neighbor);
pathToEnd = DFS(neighbor,
vertexToFind,
pathIncludingNeighbor,
visitedVertexList)
if(pathToEnd != null) {
return;
}
}
}
}
return pathToEnd;
}
public class Vertex {
public List<Vertex> adjacencyList;
}
DFS implemented using a stack.
List<Vertex> DFS(Vertex start, Vertex end) {
List<Vertex> pathToEnd = null;
Set<Vertex> visitedVertexList = new HashSet<>();
Stack<StackEntry> verticesToProcess = new Stack<>();
verticesToProcess.push(new StackEntry(vertex, new ArraryList<>());
while(!verticesToProcess.empty()) {
StackEntry entry = verticesToProcess.pop();
for(Vertex neighbor : entry.vertex.adjacencyList) {
// Make a copy of the path so far since possible paths
// will be parallel branches.
List<Vertex> currentPath = new ArrayList<>(entry.path);
currentPath.add(neighbor);
if(neighbor == end) {
pathToEnd = currentPath;
break;
}
if(!visitedVertexList.contains(neighbor)) {
// Push onto stack a new stack entry.
// Since a stack is LIFO, this provides the
// depth-first traversal of the graph.
verticesToProcess.push(new StackEntry(vertex, currentPath));
}
}
if(pathToEnd != null) {
// A path has been found.
break;
}
}
return pathToEnd;
}
public class StackEntry {
public Vertex vertex;
public List<Vertex> path;
public StackEntry(Vertex vertex, List<Vertex> path) {
this.vertex = vertex;
this.path = path;
}
}
The runtime of DFS is O(V + E).
- V: number of vertices in the graph.
- E: number of edges in the graph.
The space required for DFS is O(V).
- May need to store a set of already visited vertices.
- If a stack is used, in the worst case all vertices would need to be pushed onto the stack while searching.