Algorithm 为什么BFS的复杂性是O(V&x2B;E)而不是O(E)?
这是一个通用的BFS实现:Algorithm 为什么BFS的复杂性是O(V&x2B;E)而不是O(E)?,algorithm,time-complexity,big-o,depth-first-search,breadth-first-search,Algorithm,Time Complexity,Big O,Depth First Search,Breadth First Search,这是一个通用的BFS实现: 对于具有V节点和E边总数的连通图,我们知道每个边在内环中将被考虑两次。因此,如果BFS的内环中的迭代总数将是2*边数E,那么运行时不是将是O(E)?这是一种需要更深入地研究实现的情况。特别是,如何确定是否访问了节点 传统算法通过对顶点着色来实现这一点。所有顶点一开始都是白色的,访问时会变为黑色。因此,只需查看顶点的颜色即可确定访问。如果您使用这种方法,那么您必须在开始时将每个顶点的颜色设置为白色,从而完成相当于O(V)的初始化工作 你可以用不同的方式管理你的颜色。您
对于具有
V
节点和E
边总数的连通图,我们知道每个边在内环中将被考虑两次。因此,如果BFS的内环中的迭代总数将是2*边数E
,那么运行时不是将是O(E)
?这是一种需要更深入地研究实现的情况。特别是,如何确定是否访问了节点
传统算法通过对顶点着色来实现这一点。所有顶点一开始都是白色的,访问时会变为黑色。因此,只需查看顶点的颜色即可确定访问。如果您使用这种方法,那么您必须在开始时将每个顶点的颜色设置为白色,从而完成相当于O(V)的初始化工作
你可以用不同的方式管理你的颜色。您可以维护包含所有访问节点的数据结构。如果这样做,就可以避免O(V)初始化成本。但是,您将在数据结构的其他地方支付该费用。例如,如果您将它们全部存储在一个平衡树中,则如果w未被访问,则每个现在的成本为O(log V)
这显然给了你一个选择。您可以使用传统的着色方法生成O(V+E),也可以通过将此信息存储在您自己的数据结构中生成O(E log V)
在问题中指定一个连通图。在这种情况下,O(V+E)=O(E),因为顶点的数量永远不能超过E+1。然而,BFS的时间复杂度通常是针对一个任意图给出的,该图可以包括一个非常稀疏的图
如果一个图足够稀疏(比如一百万个顶点和五条边),那么初始化的代价可能会很大,以至于您需要切换到O(elnv)算法。然而,这些在实际环境中是非常罕见的。在实际环境中,传统方法(给每个顶点一个颜色)的速度与更花哨的数据结构相比是如此之快,以至于除了非常稀疏的图之外,您对所有东西都选择了这种传统的着色方案
如果您在顶点上维护了一个专用的颜色属性,并使用一个不变的规则,即在算法调用之间所有节点都是黑色的,那么您可以通过对每个BFS执行两次来降低O(E)的成本。在第一次传递时,可以将它们全部设置为白色,然后进行第二次传递以将它们全部变为黑色。如果您有一个非常稀疏的图,这可能会更有效。在这种情况下,您需要更深入地了解实现。特别是,如何确定是否访问了节点
传统算法通过对顶点着色来实现这一点。所有顶点一开始都是白色的,访问时会变为黑色。因此,只需查看顶点的颜色即可确定访问。如果您使用这种方法,那么您必须在开始时将每个顶点的颜色设置为白色,从而完成相当于O(V)的初始化工作
你可以用不同的方式管理你的颜色。您可以维护包含所有访问节点的数据结构。如果这样做,就可以避免O(V)初始化成本。但是,您将在数据结构的其他地方支付该费用。例如,如果您将它们全部存储在一个平衡树中,则如果w未被访问,则每个现在的成本为O(log V)
这显然给了你一个选择。您可以使用传统的着色方法生成O(V+E),也可以通过将此信息存储在您自己的数据结构中生成O(E log V)
在问题中指定一个连通图。在这种情况下,O(V+E)=O(E),因为顶点的数量永远不能超过E+1。然而,BFS的时间复杂度通常是针对一个任意图给出的,该图可以包括一个非常稀疏的图
如果一个图足够稀疏(比如一百万个顶点和五条边),那么初始化的代价可能会很大,以至于您需要切换到O(elnv)算法。然而,这些在实际环境中是非常罕见的。在实际环境中,传统方法(给每个顶点一个颜色)的速度与更花哨的数据结构相比是如此之快,以至于除了非常稀疏的图之外,您对所有东西都选择了这种传统的着色方案
如果您在顶点上维护了一个专用的颜色属性,并使用一个不变的规则,即在算法调用之间所有节点都是黑色的,那么您可以通过对每个BFS执行两次来降低O(E)的成本。在第一次传递时,可以将它们全部设置为白色,然后进行第二次传递以将它们全部变为黑色。如果你有一个非常稀疏的图,这可能会更有效。好吧,让我们把它分成几个简单的部分
您保存了一个已访问的数组,通过查找它,您可以决定是否将节点推入队列。一旦访问,您就不会再推它了。那么,有多少节点被推到队列中:(当然)V节点
。它的复杂性是O(V)
现在,每次从队列中取出一个节点
,并访问其所有相邻节点
。现在,按照这个方法,对于所有的V节点
,您将遇到多少节点。如果图形是单向的,则是边数,如果图形是双向的,则是边数。因此,对于单向的O(E)
和O(2*E)
双向的
因此,最终的(即总的)复杂性将是O(V+e)
或O(V+2*e)
或一般来说
,我们可以说O(V+e)
<
1 ---- 2
|
|
3 ---- 4