简体   繁体   中英

How can I figure out if two nodes are connected in a graph with recursive depth first search in Java?

Note: the code below now reflects a working solution to the problem, I figured out the error.

I am trying to solve the simple problem of seeing if two nodes are connected. There are many solutions available that use a stack, and I can find much DFS code that is recursive, but non that use recursion and actually search for something and return true/ false. Any help would be appreciated. Thanks!

  public static boolean routeBetween(int[][] graph, int startNode, int targetNode){

  //where we can keep track of the visited vertices
  int numberOfVertices = graph[0].length;
  boolean[] visited = new boolean[numberOfVerticies];

  //set all verticies to not visited
  for(int i=0; i<visited.length; i++){
    visited[i] = false;
  }

  return dfs(graph, visited, startNode, targetNode);
}

//where the actual dfs / recursion will happen, need this to keep track of
//visited
public static boolean dfs(int[][] graph, boolean[] visited, int startNode, int targetNode){

  if(startNode == targetNode){
    return true;
  }
  boolean foundNode = false;

  if(!visited[startNode]){
    visited[startNode] = true;
    for(int i=0; i<graph[startNode].length;i++){
      if(graph[startNode][i] ==1){
        boolean currentChild = dfs(graph, visited, i, targetNode);
        foundNode = currentChild || foundNode;
      }
    }
  }
  return foundNode;
}

Here is some code that I was using to test the above code:

  int [][] matrix = {
      {0, 1, 0, 0, 1, 1, 0, 0},
      {1, 0, 0, 0, 0, 1, 1, 0},
      {0, 0, 0, 1, 0, 0, 1, 0},
      {0, 0, 1, 0, 0, 0, 0, 1},
      {1, 0, 0, 0, 0, 1, 0, 0},
      {1, 1, 0, 0, 1, 0, 0, 0},
      {0, 1, 1, 0, 0, 0, 0, 1},
      {0, 0, 0, 1, 0, 0, 1, 0}
    };

    System.out.println(GraphTools.routeBetween(matrix,0,1));
    System.out.println(GraphTools.routeBetween(matrix,0,2));

I know that you have already figured out your issue, but sometimes it's worthwhile to see things worked out differently.

Since you are already keeping track of all the nodes that you visit in a boolean array, much of the work you do in your dfs method turns out to be redundant.

Another way to do it is as follows:

public static boolean dfs2(int[][] graph, boolean[] visited, int startNode, int targetNode) {

    // if you have not visited the current node or the target node
    // then visit this node and recursively explore its unvisited 
    //neighbors
    if (!visited[startNode] && !visited[targetNode]) {
        // visit the start node
        visited[startNode] = true;
        for (int i = 0; i < graph[startNode].length; i++) {
            if (graph[startNode][i] == 1) {
                return dfs(graph, visited, i, targetNode);
            }
        }
    }
    // otherwise we just return whether or not we have visited the
    // target node and continue... If we have visited the target node 
    //we never go into the if-statement and we always return true

    return visited[targetNode];

}

Your way is perfectly fine, I just wanted to offer an alternative solution. Hope this is helpful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM