我的BFS递归调用不会停止

时间:2013-04-05 05:59:23

标签: java graph

我有以下代码来查找起始节点和结束节点之间的所有路径。

Graph.java

 import java.util.HashMap;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.Map;
 import java.util.Set;

public class Graph {
private Map<String, LinkedHashSet<String>> map = new HashMap();

public void addEdge(String node1, String node2) {
    LinkedHashSet<String> adjacent = map.get(node1);
    if(adjacent==null) {
        adjacent = new LinkedHashSet();
        map.put(node1, adjacent);
    }
    adjacent.add(node2);
}

public void addTwoWayVertex(String node1, String node2) {
    addEdge(node1, node2);
    addEdge(node2, node1);
}

public boolean isConnected(String node1, String node2) {
    Set adjacent = map.get(node1);
    if(adjacent==null) {
        return false;
    }
    return adjacent.contains(node2);
}

public LinkedList<String> adjacentNodes(String last) {
    LinkedHashSet<String> adjacent = map.get(last);
    if(adjacent==null) {
        return new LinkedList();
    }
    return new LinkedList<String>(adjacent);
}

}

和 Search.java

 import java.util.LinkedList;

 public class Search {

private static final String START = "D";
private static final String END = "E";

public static void main(String[] args) {
    // this graph is directional
    Graph graph = new Graph();
    graph.addEdge("A", "B");
    graph.addEdge("A", "C");
    graph.addEdge("B", "A");
    graph.addEdge("B", "D");
    graph.addEdge("B", "E"); // this is the only one-way connection
    graph.addEdge("B", "F");
    graph.addEdge("C", "A");
    graph.addEdge("C", "E");
    graph.addEdge("C", "F");
    graph.addEdge("D", "B");
    graph.addEdge("E", "C");
    graph.addEdge("E", "F");
    graph.addEdge("F", "B");
    graph.addEdge("F", "C");
    graph.addEdge("F", "E");
    LinkedList<String> visited = new LinkedList();
    visited.add(START);
    new Search().breadthFirst(graph, visited);
}

private void breadthFirst(Graph graph, LinkedList<String> visited) {
    LinkedList<String> nodes = graph.adjacentNodes(visited.getLast());
    // examine adjacent nodes
    for (String node : nodes) {
        if (visited.contains(node)) {
            continue;
        }
        if (node.equals(END)) {
            visited.add(node);
            printPath(visited);
            visited.removeLast();
            return ;
            //break;
        }
    }
    // in breadth-first, recursion needs to come after visiting adjacent nodes
    for (String node : nodes) {
        if (visited.contains(node) || node.equals(END)) {
            continue;
        }
        visited.addLast(node);
        breadthFirst(graph, visited);
        visited.removeLast();
    }
}

private void printPath(LinkedList<String> visited) {
    for (String node : visited) {
        System.out.print(node);
        System.out.print(" ");
    }
    System.out.println();
}
}

我想在找到两个节点之间的第一条路径后停止递归调用。 break语句之前的return语句工作正常,但如果我添加许多无向边,它不会停止打印两个节点之间的所有路径。

1 个答案:

答案 0 :(得分:0)

在BFS中,您必须“着色”节点以了解您是否已经访问过这些节点。

http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/GraphAlgor/breadthSearch.htm

为了跟踪进度,广度优先搜索每个顶点的颜色。图的每个顶点都处于以下三种状态之一:

  1. 未被发现;
  2. 发现但未完全探索;和
  3. 充分探索。
  4. 顶点的状态u存储在颜色变量中,如下所示:

    1. color [u] = White - 表示“未发现”状态,
    2. color [u] = Gray - 表示“已发现但未完全探索”状态,
    3. color [u] = Black - 用于“完全探索”状态。