我理解图遍历中BFS的时间复杂度为O( V + E )
,因为在最坏的情况下,每个顶点和每个边都会被探索。
嗯,确切的时间复杂度v+2E
??
每个顶点都被探索一次+每个相邻的顶点
graph= No of edges*2= 2E
因此时间复杂度为n+2E
..我是否正确?
答案 0 :(得分:1)
对于随机图表,时间复杂度为O(V+E)
:Breadth-first search
如链接中所述,根据图表的拓扑结构,O(E)
可能会有O(V)
(如果您的图表是非循环的)到O(V^2)
(如果所有顶点都连接在一起)彼此)。
因此,根据图表的拓扑结构,时间复杂度从O(V + V) = O(V)
到O(V + V^2) = O(V^2)
不等。
此外,自|V| <= 2 |E|
起,O(3E) = O(E)
也是正确的,但界限更宽松。
答案 1 :(得分:0)
我们假设G是连通的和无向的。如果未连接,则可以将以下想法独立应用于G的每个连接组件。另外,假设G表示为邻接列表,对于每个顶点v,我们可以决定是否在O(1)时间内访问v,例如使用查找表。
如果您想计算BFS中的确切步数,您可以观察到:
由于G连接,BFS将只访问每个顶点一次,因此我们计算| V |在节点中访问。请注意,在一次访问中,您可以执行更多操作,而不是计算边缘上的循环,而不仅仅是标记当前访问的顶点。
对于我们想要计算的每个顶点v,BFS在此顶点检查的边数。
您必须遍历v的所有边缘才能执行BFS。如果跳过一条边,则很容易证明BFS不正确。所以每个边缘都要检查两次。
这里可能会出现一个问题。有人可能会问,如果需要检查顶点v中的边(p,v),其中p是已经构造的BFS树中v的父亲,即我们直接从p来到v。当然,你不必考虑这个优势,但决定跳过这个优势还需要至少花费一个额外的操作:
for (v, u) in v.edges:
if u == p: # p is the parent of v in already constructed tree
continue
if not visited[u]:
BFS(u, parent=v)
它检查下面代码的边数相同,但具有更高的复杂度,因为对于除了一个边之外的所有边,我们运行两个if语句而不是一个。
for (v, u) in v.edges:
if not visited[u]: # if p is the parent of v, then p is already visited
BFS(u, parent=v)
你甚至可以开发一种不同的方法来跳过边缘(v,p),但它总是需要至少一次操作,所以这是一种浪费的努力。