广度优先与深度优先
遍历树/图时,广度优先和深度优先有什么区别? 任何编码或伪代码示例都很棒。
When Traversing a Tree/Graph what is the difference between Breadth First and Depth first? Any coding or pseudocode examples would be great.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这两个术语区分了两种不同的行走树的方式。
展示差异可能是最简单的。 考虑一下树:
深度优先遍历将按此顺序访问节点。
请注意,在继续前进之前,您会一直向下一条腿。
广度优先遍历将按此顺序访问节点。
在这里,我们在向下遍历之前跨每个级别。
(请注意,遍历顺序存在一些模糊性,并且我在树的每个级别都维持了“读取”顺序。在任何一种情况下,我都可以在 C 之前或之后到达 B,同样我也可以到达E在F之前或之后。这个可能重要也可能不重要,取决于你的应用程序...)
两种遍历都可以用伪代码实现:
两种遍历顺序的区别在于
Container的选择.
递归实现看起来像
当到达没有子节点的节点时,递归结束,因此保证结束
有限的非循环图。
到了这一步,我还是有点作弊了。 只要稍微聪明一点,您还可以按以下顺序处理节点:
这是深度优先的变体,在返回之前我不会在每个节点上进行工作那个树。 然而,我在向下的过程中访问了更高的节点来找到它们的孩子。
这种遍历在递归实现中相当自然(使用上面的“Alternate time”行而不是第一个“Work”行),如果您使用显式堆栈,则不会太困难,但我会将其作为练习。
These two terms differentiate between two different ways of walking a tree.
It is probably easiest just to exhibit the difference. Consider the tree:
A depth first traversal would visit the nodes in this order
Notice that you go all the way down one leg before moving on.
A breadth first traversal would visit the node in this order
Here we work all the way across each level before going down.
(Note that there is some ambiguity in the traversal orders, and I've cheated to maintain the "reading" order at each level of the tree. In either case I could get to B before or after C, and likewise I could get to E before or after F. This may or may not matter, depends on you application...)
Both kinds of traversal can be achieved with the pseudocode:
The difference between the two traversal orders lies in the choice of
Container
.The recursive implementation looks like
The recursion ends when you reach a node that has no children, so it is guaranteed to end for
finite, acyclic graphs.
At this point, I've still cheated a little. With a little cleverness you can also work-on the nodes in this order:
which is a variation of depth-first, where I don't do the work at each node until I'm walking back up the tree. I have however visited the higher nodes on the way down to find their children.
This traversal is fairly natural in the recursive implementation (use the "Alternate time" line above instead of the first "Work" line), and not too hard if you use a explicit stack, but I'll leave it as an exercise.
理解术语:
这张图片应该能让您了解使用“宽度”和“深度”这两个词的上下文。
深度优先搜索:
深度优先搜索算法的行为就好像它想要尽可能远
尽可能快地从起点开始。
它通常使用一个
Stack
来记住当它到达死胡同时应该去哪里。遵循的规则:将第一个顶点 A 推入
Stack
Java代码:
应用:深度优先搜索通常用于模拟游戏(以及现实世界中类似游戏的情况)。 在典型的游戏中,您可以选择几种可能的操作之一。 每个选择都会导致进一步的选择,每个选择都会导致进一步的选择,依此类推,形成一个不断扩大的树形可能性图。
广度优先搜索:
到起点。
Java代码:
应用:广度优先搜索首先查找满足以下条件的所有顶点:距起点一条边,然后是距起点两条边的所有顶点,依此类推。 如果您试图找到从起始顶点到给定顶点的最短路径,这非常有用。
希望这足以理解广度优先和深度优先搜索。 为了进一步阅读,我推荐 Robert Lafore 所著的一本优秀的数据结构书中的“图表”章节。
Understanding the terms:
This picture should give you the idea about the context in which the words breadth and depth are used.
Depth-First Search:
Depth-first search algorithm acts as if it wants to get as far away
from the starting point as quickly as possible.
It generally uses a
Stack
to remember where it should go when it reaches a dead end.Rules to follow: Push first vertex A on to the
Stack
Java code:
Applications: Depth-first searches are often used in simulations of games (and game-like situations in the real world). In a typical game you can choose one of several possible actions. Each choice leads to further choices, each of which leads to further choices, and so on into an ever-expanding tree-shaped graph of possibilities.
Breadth-First Search:
to the starting point.
Queue
.Java code:
Applications: Breadth-first search first finds all the vertices that are one edge away from the starting point, then all the vertices that are two edges away, and so on. This is useful if you’re trying to find the shortest path from the starting vertex to a given vertex.
Hopefully that should be enough for understanding the Breadth-First and Depth-First searches. For further reading I would recommend the Graphs chapter from an excellent data structures book by Robert Lafore.
给定这个二叉树:
广度优先遍历:
从左到右遍历每个级别。
“我是 G,我的孩子是 D 和 I,我的孙子是 B、E、H 和 K,他们的孙子是 A、C、F”
< strong>深度优先遍历:
遍历并不是一次跨越整个关卡。 相反,遍历首先深入到树的深度(从根到叶)。 但是,它比简单的向上和向下要复杂一些。
共有三种方法:
用法(又名,我们为什么关心):
我真的很喜欢 Quora 对深度优先遍历方法及其常用方法的简单解释:
“按序遍历将打印值[按 BST(二叉搜索树)的顺序]”
“前序遍历用于创建[二叉搜索树]的副本。”
“后序遍历用于删除[二叉搜索树]。”
https://www.quora.com/What-is-the-use-of-pre-order-and-post-order-traversal-of-binary-trees-in-computing
Given this binary tree:
Breadth First Traversal:
Traverse across each level from left to right.
"I'm G, my kids are D and I, my grandkids are B, E, H and K, their grandkids are A, C, F"
Depth First Traversal:
Traversal is not done ACROSS entire levels at a time. Instead, traversal dives into the DEPTH (from root to leaf) of the tree first. However, it's a bit more complex than simply up and down.
There are three methods:
Usage (aka, why do we care):
I really enjoyed this simple Quora explanation of the Depth First Traversal methods and how they are commonly used:
"In-Order Traversal will print values [in order for the BST (binary search tree)]"
"Pre-order traversal is used to create a copy of the [binary search tree]."
"Postorder traversal is used to delete the [binary search tree]."
https://www.quora.com/What-is-the-use-of-pre-order-and-post-order-traversal-of-binary-trees-in-computing
我认为以一种方式编写它们会很有趣,只需切换几行代码就会给你一个算法或另一个算法,这样你就会发现你的困境并不像一开始看起来那么强烈。
我个人喜欢将 BFS 解释为淹没景观:低海拔地区将首先被淹没,然后才是高海拔地区。 如果你把景观高度想象成我们在地理书上看到的等值线,很容易看出 BFS 同时填充了同一条等值线下的所有区域,就像物理学中的情况一样。 因此,将高度解释为距离或缩放成本给出了算法的非常直观的想法。
考虑到这一点,您可以轻松地采用广度优先搜索背后的思想来轻松找到最小生成树、最短路径以及许多其他最小化算法。
我还没有看到 DFS 的任何直观解释(只有关于迷宫的标准解释,但它不如 BFS 和洪水那么强大),所以对我来说,BFS 似乎与上述物理现象有更好的相关性,而DFS 与理性系统上的选择困境(即人或计算机决定在国际象棋游戏中采取哪一步或走出迷宫)有更好的相关性。
因此,对我来说,两者之间的区别在于哪种自然现象最符合其在现实生活中的传播模型(横向)。
I think it would be interesting to write both of them in a way that only by switching some lines of code would give you one algorithm or the other, so that you will see that your dillema is not so strong as it seems to be at first.
I personally like the interpretation of BFS as flooding a landscape: the low altitude areas will be flooded first, and only then the high altitude areas would follow. If you imagine the landscape altitudes as isolines as we see in geography books, its easy to see that BFS fills all area under the same isoline at the same time, just as this would be with physics. Thus, interpreting altitudes as distance or scaled cost gives a pretty intuitive idea of the algorithm.
With this in mind, you can easily adapt the idea behind breadth first search to find the minimum spanning tree easily, shortest path, and also many other minimization algorithms.
I didnt see any intuitive interpretation of DFS yet (only the standard one about the maze, but it isnt as powerful as the BFS one and flooding), so for me it seems that BFS seems to correlate better with physical phenomena as described above, while DFS correlates better with choices dillema on rational systems (ie people or computers deciding which move to make on a chess game or going out of a maze).
So, for me the difference between lies on which natural phenomenon best matches their propagation model (transversing) in real life.