我理解DFS和BFS之间的区别,但是我想知道在选择DFS和BFS时应该考虑哪些因素。

比如对于非常深的树避免DFS,等等。


当前回答

来自 http://www.programmerinterview.com/index.php/data-structures/dfs-vs-bfs/

一个BFS的例子

这里有一个BFS的例子。这类似于级别顺序树遍历,其中我们将使用迭代方法的队列(大多数递归将最终使用DFS)。数字表示BFS中节点被访问的顺序:

在深度优先搜索中,从根开始,尽可能地跟随树的一个分支,直到找到要查找的节点或找到叶节点(没有子节点)。如果您选中了一个叶节点,那么您将继续在最近的具有未探索的子节点的父节点上搜索。

DFS的一个例子

下面是一个DFS的示例。我认为二叉树中的后序遍历将首先从叶层开始工作。数字表示DFS中节点被访问的顺序:

DFS和BFS的区别

比较BFS和DFS, DFS的最大优势是它的内存需求比BFS低得多,因为它不需要在每一层存储所有的子指针。根据数据和您正在寻找的内容,DFS或BFS都可能是有利的。

For example, given a family tree if one were looking for someone on the tree who’s still alive, then it would be safe to assume that person would be on the bottom of the tree. This means that a BFS would take a very long time to reach that last level. A DFS, however, would find the goal faster. But, if one were looking for a family member who died a very long time ago, then that person would be closer to the top of the tree. Then, a BFS would usually be faster than a DFS. So, the advantages of either vary depending on the data and what you’re looking for.

另一个例子是Facebook;关于朋友的朋友的建议。我们需要直接的朋友建议我们在哪里可以使用BFS。可能是寻找最短路径或检测周期(使用递归),我们可以使用DFS。

其他回答

根据DFS和BFS的性质。 例如,当我们要求最短路径时。 我们通常使用bfs,它可以保证“最短”。 但是DFS只能保证我们可以从这一点可以到达那一点,不能保证‘最短’。

因为深度优先搜索在处理节点时使用堆栈,所以DFS提供回溯。由于宽度优先搜索使用队列而不是堆栈来跟踪正在处理的节点,BFS不提供回溯。

以下是对你的问题的全面回答。

简单来说:

Breadth First Search (BFS) algorithm, from its name "Breadth", discovers all the neighbours of a node through the out edges of the node then it discovers the unvisited neighbours of the previously mentioned neighbours through their out edges and so forth, till all the nodes reachable from the origional source are visited (we can continue and take another origional source if there are remaining unvisited nodes and so forth). That's why it can be used to find the shortest path (if there is any) from a node (origional source) to another node if the weights of the edges are uniform.

Depth First Search (DFS) algorithm, from its name "Depth", discovers the unvisited neighbours of the most recently discovered node x through its out edges. If there is no unvisited neighbour from the node x, the algorithm backtracks to discover the unvisited neighbours of the node (through its out edges) from which node x was discovered, and so forth, till all the nodes reachable from the origional source are visited (we can continue and take another origional source if there are remaining unvisited nodes and so forth).

Both BFS and DFS can be incomplete. For example if the branching factor of a node is infinite, or very big for the resources (memory) to support (e.g. when storing the nodes to be discovered next), then BFS is not complete even though the searched key can be at a distance of few edges from the origional source. This infinite branching factor can be because of infinite choices (neighbouring nodes) from a given node to discover. If the depth is infinite, or very big for the resources (memory) to support (e.g. when storing the nodes to be discovered next), then DFS is not complete even though the searched key can be the third neighbor of the origional source. This infinite depth can be because of a situation where there is, for every node the algorithm discovers, at least a new choice (neighbouring node) that is unvisited before.

因此,我们可以得出什么时候使用BFS和DFS。假设我们正在处理一个可管理的有限分支因子和一个可管理的有限深度。如果搜索的节点很浅,即在原始源的一些边之后可以到达,那么最好使用BFS。另一方面,如果搜索的节点较深,即从原始源处经过大量边后可以到达,那么最好使用DFS。

For example, in a social network if we want to search for people who have similar interests of a specific person, we can apply BFS from this person as an origional source, because mostly these people will be his direct friends or friends of friends i.e. one or two edges far. On the other hand, if we want to search for people who have completely different interests of a specific person, we can apply DFS from this person as an origional source, because mostly these people will be very far from him i.e. friend of friend of friend.... i.e. too many edges far.

Applications of BFS and DFS can vary also because of the mechanism of searching in each one. For example, we can use either BFS (assuming the branching factor is manageable) or DFS (assuming the depth is manageable) when we just want to check the reachability from one node to another having no information where that node can be. Also both of them can solve same tasks like topological sorting of a graph (if it has). BFS can be used to find the shortest path, with unit weight edges, from a node (origional source) to another. Whereas, DFS can be used to exhaust all the choices because of its nature of going in depth, like discovering the longest path between two nodes in an acyclic graph. Also DFS, can be used for cycle detection in a graph.

最后,如果我们有无限的深度和无限的分支因子,我们可以使用迭代深化搜索(IDS)。

当树的深度可以变化时,宽度优先搜索通常是最好的方法,并且您只需要搜索树的一部分来寻找解决方案。例如,寻找从起始值到最终值的最短路径是使用BFS的好地方。

深度优先搜索通常用于需要搜索整个树的情况。它比BFS更容易实现(使用递归),并且需要更少的状态:BFS需要存储整个“边界”,DFS只需要存储当前元素的父节点列表。

当树的宽度非常大,深度很低时,使用DFS作为递归堆栈不会溢出。当宽度很低而深度很大时使用BFS遍历树。