DFS算法从右到左搜索

时间:2016-09-27 21:28:51

标签: java search tree depth-first-search

我已经编写了深度优先搜索算法,但它正在从树的右侧向左侧搜索。我可以从我的代码中看到它为什么会这样做,但是我无法想出一个改变它的解决方案,以便从左到右进行搜索。

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);
    }
}

3 个答案:

答案 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中移除) - 但这超出了你的问题的范围