我有一个图表,我想在两个节点(数字3和5)之间找到一条路径。
我读到了关于在图中查找路径的内容,我尝试编写DFS和BFS。两者都实施并运作良好。但是,我想从3到5直接访问每个节点的列表。 两种算法都按预期工作,当运行bsf时,我将按以下顺序访问节点:2,6,1,4,5。 使用dfs 2,1,4,5。 但我想要达到的目标是6,5(第一种情况下)和2,4,5(第二种情况)。
换句话说,我想只保存3到5路上的节点(在dfs / bfs期间不是所有访问过的节点),作为节点列表。
我长期以来一直绞尽脑汁,如何改变我的代码来实现它,或者我应该改变自己的方法?我应该将节点存储在正确的路径中,还是使用不同的算法?我根本不知道该怎么做。
我的bfs
public List<Node> bfs(Node root, Node nodeWeSearchFor)
{ Queue<Node> queue = new LinkedList<Node>();
List<Node> route = new ArrayList<Node>();
if(root == null || nodeWeSearchFor == null) return route;
//State is just an enum Visited or unvisited
root.state = State.Visited;
//Adds to end of queue
queue.add(root);
while(!queue.isEmpty())
{
//removes from front of queue
Node r = queue.remove();
//Visit child first before grandchild
for(Node n: r.getConnectedNodes())
{
if(n.state == State.Unvisited)
{
queue.add(n);
route.add(n);
n.state = State.Visited;
//If we found node, return
if(n==nodeWeSearchFor){
return route;
}
}
}
}
return route;}
我的dfs:
public List<Node> dfs(Node root, Node nodeWeSearchFor)
{
List<Node> route = new ArrayList<Node>();
//Avoid infinite loops
if(root == null) return route;
System.out.print(root.toString() + "\t");
root.state = State.Visited;
route.add(root);
if(root == nodeWeSearchFor) return route;
//for every child
for(Node n: root.getConnectedNodes())
{
//if childs state is not visited then recurse
if(n.state == State.Unvisited)
{
//recursive call for dfs (We are passing route)
dfs(n,nodeWeSearchFor,route);
}
}
return route;
}
public List<Node> dfs(Node root, Node nodeWeSearchFor,List<Node> _route)
{
List<Node> route = _route;
//Avoid infinite loops
if(root == null) return route;
System.out.print(root.toString() + "\t");
root.state = State.Visited;
route.add(root);
if(root == nodeWeSearchFor) return route;
//for every child
for(Node n: root.getConnectedNodes())
{
//if childs state is not visited then recurse
if(n.state == State.Unvisited)
{
dfs(n,nodeWeSearchFor,route);
}
}
return route;
}
答案 0 :(得分:1)
很容易,在DFS中,当你到达“结束”(你不能前进)时,你必须“回去”。因此,当您“返回”时,您只需从访问节点列表中的“死胡同”中删除该节点。
在BFS中,您必须为每个访问的节点创建新列表,复制已经访问过的“打开他”节点的节点,然后将其自身添加到该列表中。