I have a project where I'm to implement a DFS using a direct graph. The implementation should print the currently visited vertex, the parent (the node from which the current node was reached), and the discovery and finish time for each node.
Using these graph values:
int[] vertices = {1,2,3,4,5,6,7};
int[][] edges = {{1,2},{1,6},{2,3},{2,4},{2,5},{3,5},{4,5},{5,1},{6,4},{6,7}};
I get these results:
Vertex: 5 Parent: 3 Discovery: 0 Finished: 0
Vertex: 3 Parent: 3 Discovery: 0 Finished: 1
Vertex: 4 Parent: 2 Discovery: 2 Finished: 2
Vertex: 2 Parent: 2 Discovery: 0 Finished: 3
Vertex: 6 Parent: 1 Discovery: 4 Finished: 4
Vertex: 1 Parent: 1 Discovery: 0 Finished: 5
I think my implementation is correct, but I'm very new to graphs and would appreciate a review of my implementation.
Here is the actual code:
DfsSimulator
public class DfsSimulator {
public static void main(String[] args) {
int[] vertices = {1,2,3,4,5,6,7};
int[][] edges = {{1,2},{1,6},{2,3},{2,4},{2,5},{3,5},{4,5},{5,1},{6,4},{6,7}};
Graph graph = new AdjacencyList(vertices.length);
for(int i = 0; i < edges.length; i++) {
graph.addEdge(edges[i][0], edges[i][1]);
}
Searcher search = new Searcher(graph);
search.dfs(graph.getAdj(), vertices[0]);
}
}
Graph
import java.util.List;
import java.util.ArrayList;
public interface Graph {
public void addEdge(int i, int j);
public void removeEdge(int i, int j);
public boolean hasEdge(int i, int j);
public List<Integer> outEdges(int i);
public List<Integer> inEdges(int i);
public int getNumberVertices();
public ArrayList<ArrayList<Integer>> getAdj();
}
AdjacencyList
import java.util.List;
import java.util.ArrayList;
public class AdjacencyList implements Graph {
private int numOfVertices;
private ArrayList<ArrayList<Integer>> adj;
public AdjacencyList(int numOfVertices) {
this.numOfVertices = numOfVertices;
adj = new ArrayList<ArrayList<Integer>>(numOfVertices);
for(int i = 0; i < numOfVertices; i++) {
adj.add(new ArrayList<Integer>());
}
}
@Override
public void addEdge(int i, int j) {
adj.get(i).add(j);
}
@Override
public void removeEdge(int i, int j) {
List<Integer> edges = adj.get(i);
for(Integer integer : edges) {
if(integer == j) {
edges.remove(integer);
return;
}
}
}
@Override
public boolean hasEdge(int i, int j) {
return adj.get(i).contains(j);
}
@Override
public List<Integer> outEdges(int i) {
return adj.get(i);
}
@Override
public List<Integer> inEdges(int i) {
List<Integer> edges = new ArrayList<Integer>();
for(int j = 0; j < numOfVertices; j++) {
if(adj.get(j).contains(i)) {
edges.add(j);
}
}
return edges;
}
@Override
public int getNumberVertices() {
return numOfVertices;
}
@Override
public ArrayList<ArrayList<Integer>> getAdj() {
return adj;
}
}
Searcher
import java.util.List;
import java.util.ArrayList;
public class Searcher {
private int time = 0;
private int[] d;
private int[] f;
private int parent;
public Searcher(Graph graph) {
d = new int[graph.getNumberVertices()];
f = new int[graph.getNumberVertices()];
}
public void dfs(ArrayList<ArrayList<Integer>> adj, int r) {
int n = adj.size();
boolean[] visited = new boolean[n];
dfs(adj, r, visited);
}
private void dfs(ArrayList<ArrayList<Integer>> adj, int i, boolean[] visited) {
visited[i] = true;
d[i] = time;
for(int j : adj.get(i)) {
if(j == adj.size()) { continue; }
if(!visited[j]) {
parent = i;
dfs(adj, j, visited);
}
}
f[i] = time;
time++;
System.out.println("Vertex: " + i + " Parent: " + parent +
" Discovery: " + d[i] + " Finished: " + f[i]);
}
public int getTime() { return time; }
public int[] getDiscoveryTimes() { return d; }
public int[] getFinishTimes() { return f; }