我已经编写了深度优先搜索算法,但它正在从树的右侧向左侧搜索。我可以从我的代码中看到它为什么会这样做,但是我无法想出一个改变它的解决方案,以便从左到右进行搜索。
public class DFS {
public LinkedList<Node> search(Node root, Node target) {
LinkedList<Node> open = new LinkedList<>();
LinkedList<Node> closed = new LinkedList<>();
open.addLast(root);
while (!open.isEmpty()) {
Node current = open.removeFirst();
if (current.equals(target)) {
closed.addLast(current);
return closed;
}
else {
ArrayList<Node> children = current.getChildren();
closed.addLast(current);
for (Node child : children) {
if (!open.contains(child) && !closed.contains(child)) {
open.addFirst(child);
}
}
}
}
return null;
}
}
closed
是按访问顺序访问的节点列表。
Node.getChildren()
按照添加顺序返回节点子节点的ArrayList。
修改
这是节点类:
public class Node {
private ArrayList<Node> children;
private String name;
public Node(String name){
children = new ArrayList<Node>();
this.name = name;
}
public ArrayList<Node> getChildren(){
return new ArrayList<Node>(children);
}
public Node addChild(Node child){
children.add(child);
return child;
}
public void removeChild(Node child){
children.remove(child);
}
public String getName() {
return name;
}
public boolean equals(Node other){
return (this.getName().compareTo(other.getName())==0);
}
}
答案 0 :(得分:1)
如果你的DFS确实依赖于方向,反转你的孩子,或者添加第一个而不是addLast?
答案 1 :(得分:0)
getChildren包含元素1..n
然后你有一个“打开”的堆栈,每次执行主循环时都会弹出第一个元素。
你通过将孩子推到堆栈的前面($('#yourElement').addClass('yourClass');
$('#yourElement').removeClass('yourClass');
if ( $('#yourElement').hasClass('yourClass') DO SOMETHING)
)来填充这个堆栈,然后在1..n你以n..1结束(插入1,它现在是第一个,插入2,它现在是第一,1是第二,依此类推。)
从最后一个索引弹出打开,或者将子节点推送到堆栈的末尾,它应该可以工作,除非getChildren没有按照你声明的顺序返回。
答案 2 :(得分:0)
对“如何避免从右到左”问题的简单回答是:
ArrayList<Node> children = current.getChildren();
closed.addLast(current);
// *** Not like this ***
// for (Node child : children) {
// if (!open.contains(child) && !closed.contains(child)) {
// open.addFirst(child);
// }
//}
// **** But like this ****
for(int i=children.size()-1; i>=0; i-- ) {
Node child=children.get(i);
if (!open.contains(child) && !closed.contains(child)) {
open.addFirst(child);
}
}
// If you are **absolutely** sure your structure is a
// Tree (thus, no cycles) then testing against
// open/closed is unnecessary and the code can be simplified: as
// open.addAll(0, children);
你的算法无论如何都是有缺陷的:没有规定在树中结束/丢弃未能产生结果的下行路径(你永远不会从closed
中移除) - 但这超出了你的问题的范围