我已经盯着这个看了几个小时了,不知道出了什么问题,
我正在尝试实现一种使用深度优先搜索算法来确定图形中两个顶点之间是否存在路径的方法。
但是,虽然看起来可以成功找到所需的顶点,但它没有到达return语句。
我尝试使用不同的变量,打印内容,更改订单,但无法使它返回true。任何帮助将不胜感激!
public class Path<V,E> {
private HashMap<V,Boolean> visited = new HashMap<V,Boolean>();
public boolean pathExists(Graph<V,E> graph, V v1, V v2) {
if (v1.equals(v2)) {
System.out.println("v1 = v2");
return true;
}
if (!visited.containsKey(v1)) {
System.out.println("v1 discovered: "+v1);
visited.put(v1, true);
}
for (V v : graph.getNeighbors(v1)) {
if (v.equals(v2)) {
visited.clear();
System.out.println("v discovered: "+v);
return true;
}
if (!visited.containsKey(v)) {
visited.put(v,true);
System.out.println("visited doesn't contain v: "+v);
System.out.println("starting new search with "+v);
pathExists(graph,v,v2);
}
}
visited.clear();
return false;
}
public static void main(String[] args) {
MyGraph<String,String> mg = new MyGraph<String,String>();
Path<String,String> path = new Path<String,String>();
mg.insertVertex("utrecht");
mg.insertVertex("amsterdam");
mg.insertVertex("maastricht");
mg.insertEdge("utrecht", "amsterdam", "route1", 2);
mg.insertEdge("amsterdam", "maastricht", "route2", 1);
boolean c = path.pathExists(mg, "utrecht", "maastricht");
System.out.println(c);
}
}
这是控制台输出。
v1 discovered: utrecht<br>
visited doesn't contain v: amsterdam<br>
starting new search with amsterdam<br>
v discovered: maastricht<br>
false<br>
因为它正在打印“ v found:maastricht”,所以我希望它返回true,但返回false。
答案 0 :(得分:0)
程序中有两个主要错误。
找到顶点后,您确实返回了true
,但是您没有使用返回值。由于您的方法是递归的,因此返回值会丢失。
代替
pathExists(graph,v,v2);
您应该写
if(pathExists(graph,v,v2)) return true;
您在递归过程中错误地清除了访问过的地图。
首先,完全不需要,除非您以后需要重用访问过的地图。但是即使在这种情况下,最好还是在方法之外清除它。
尽管visited.clear()
下的if (v.equals(v2))
并不是真正的问题(除了前面的说明),但是for循环之后的第二个会创建错误。
例如,考虑以下顶点及其邻接列表:
1 -> [2, 4]
2 -> [3]
4 -> [1, 5]
5 -> []
假设您要寻找顶点5
,然后从顶点1
开始。您将访问顶点2
和顶点3
。您的visited
地图包含[1,2,3]
。顶点pathExists
的{{1}}的结尾,因为您没有发现3
和5
没有邻居,因此请清除3
映射。然后,您访问顶点visited
,由于您清除了地图,因此它仅包含4
。因此,您再次访问[4]
,依此类推。
这实际上不是错误,但是不需要创建1
。只需创建一个Map<Integer, Boolean>
并检查顶点是否存在。