简体   繁体   English

在Java中将广度优先搜索转换为深度优先搜索

[英]Converting a Breadth First Search to Depth first Search in Java

its been a long time since I touched Java so this may seem like an odd question. 自从接触Java以来​​已经有很长时间了,所以这似乎是一个奇怪的问题。 Currently have this Breadth First Search code I found here on StackOverflow, I have it modified on my end but I'll post the original code here. 目前,我已经在StackOverflow上找到了此“广度优先搜索”代码,我对它进行了修改,但我将在此处发布原始代码。

public List<Node> getDirections(Node start, Node finish){
    List<Node> directions = new LinkedList<Node>();
    Queue<Node> q = new LinkedList<Node>();
    Node current = start;
    q.add(current);
    while(!q.isEmpty()){
        current = q.remove();
        directions.add(current);
        if (current.equals(finish)){
            break;
        }else{
            for(Node node : current.getOutNodes()){
                if(!q.contains(node)){
                        q.add(node);
                }
            }
        }
    }
    if (!current.equals(finish)){
        System.out.println("can't reach destination");
}
return directions;
}

I'm aware of other depth first search algorithms out there, but I was also told its possible to convert breadth first search to depth first search easily, and I would understand it better if it was done to this code instead of 2 totally different codes. 我知道那里有其他深度优先搜索算法,但是我还被告知可以将广度优先搜索轻松转换为深度优先搜索,如果对这部分代码进行编码而不是2个完全不同的代码,我会更好地理解它。 。

How can I change this to be a Depth First Search? 如何将其更改为深度优先搜索?

The main difference between Depth first and Breadth fist is the order in which you explore the nodes in your "frontier" (the list of nodes you're yet to explore). “深度优先”与“广度拳头”之间的主要区别在于,您探索“边界”中的节点的顺序(尚未探索的节点列表)。

If you add the outgoing nodes from your current node to the end of that list, you'll be testing every possibility in a "level" (for simplification purposes, imagine this as a tree), before going to the next level, so you have a Breadth first search. 如果将当前节点的传出节点添加到该列表的末尾,则在进入下一个级别之前,将在“级别”(为了简化起见,将其想象成一棵树)中测试所有可能性,因此,进行广度优先搜索。

If, on the other hand, you explore the newly added nodes (the outgoing nodes from your current position), before the nodes you've added earlier (that belong in the "upper" levels of the tree), then you'll be exploring the depth of the tree first. 另一方面,如果您在之前添加的节点(属于树的“较高”级别)之前探索新添加的节点(当前位置的传出节点),则您将首先探索树的深度。

In terms of data structures, you want a Stack instead of a Queue, but I think the explanation may come in handy. 在数据结构方面,您需要堆栈而不是队列,但是我认为解释可能会派上用场。

You'd have to replace q.add(node) (which adds at the end of a list) with q.add(0, node) (to add at the beginning). 您必须将q.add(node) (在列表末尾添加)替换为q.add(0, node) (在开始处添加)。 Basically, use a stack instead of a queue . 基本上,使用stack而不是queue

Obviously you'd have to use the List interface instead of the Queue one to access the LinkedList . 显然,您必须使用List接口而不是Queue接口来访问LinkedList

Deque<Node> q = new LinkedList<Node>();

and use pop and push instead of remove and add 并使用poppush而不是removeadd

basically remove from the same side you added (normal remove and add are LIFO queue base ops) depth first uses a FIFO stack 基本上从添加的同一面remove (正常removeadd是LIFO队列基础操作),深度首先使用FIFO堆栈

and the other search algorithms are essentially the same but use different types of queues (eager search uses a easiest next step for example) 和其他搜索算法基本相同,但是使用不同类型的队列(例如,急切的搜索使用最简单的下一步)

Stack替换QueueLinkedList ,用push add ,用pop remove

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM