为什么DFS和BFS的时间复杂度为O(V + E)


132

BFS的基本算法:

set start vertex to visited

load it into queue

while queue not empty

   for each edge incident to vertex

        if its not visited

            load into queue

            mark vertex

所以我认为时间复杂度是:

v1 + (incident edges) + v2 + (incident edges) + .... + vn + (incident edges) 

v顶点1到哪里n

首先,我所说的正确吗?其次,这是如何的O(N + E),以及关于其原因的直觉将非常好。谢谢

Answers:


268

你的钱

v1 + (incident edges) + v2 + (incident edges) + .... + vn + (incident edges)

可以改写成

(v1 + v2 + ... + vn) + [(incident_edges v1) + (incident_edges v2) + ... + (incident_edges vn)]

第一组是,O(N)而另一组是O(E)


1
但是必须从队列中提取每个顶点,这就是log(| Q |)这部分呢?
Yola

3
log(| Q |)<log(N)<N,因此您可以放心地忽略渐近项
Mihai Maruseac 2016年

2
如果在邻接列表中,每个顶点都连接到所有其他顶点,那么复杂度将等于O(V + E)= O(V + V ^ 2)= O(V ^ 2)。E = V ^ 2,因为最多的边数= V ^ 2。
最多

根据您的回答,复杂度不会变为O(V + 2E)吗?既然每个边缘可能与另一个边缘有一个共同的边缘?
karansky '17

2
常数项可以删除。
Mihai Maruseac'5

41

DFS(分析):

  • 设置/获取顶点/边缘标签需要花费O(1)时间
  • 每个顶点被标记两次
    • 曾经是UNEXPLORED
    • 一次访问
  • 每个边缘被标记两次
    • 曾经是UNEXPLORED
    • 一次作为DISCOVERY或BACK
  • 每个顶点调用一次方法eventsEdges
  • O(n + m)如果图表由邻接表结构表示,DFS将及时运行
  • 回想起那个 Σv deg(v) = 2m

BFS(分析):

  • 设置/获取顶点/边标签需要O(1)时间
  • 每个顶点被标记两次
    • 曾经是UNEXPLORED
    • 一次访问
  • 每个边缘被标记两次
    • 曾经是UNEXPLORED
    • 一次作为发现或交叉
  • 每个顶点一次插入到序列中 Li
  • 每个顶点调用一次方法eventsEdges
  • BFS O(n + m)及时运行,前提是该图由邻接表结构表示
  • 回想起那个 Σv deg(v) = 2m

Tnx的编辑,我是新来的,所以我仍然尝试使用编辑屏幕进行管理:)
TheNewOne

1
感谢您通过提及图将由邻接表结构表示来进行具体说明,这使我感到困惑,为什么DFS为O(n + m),我认为它为O(n + 2m),因为每个边都经过了两次通过回溯。
mib1413456 2014年

22

无需太多手续就可以非常简化:每个边缘被精确地视为两次,并且每个节点都被精确地处理一次,因此复杂性必须是边缘数量和顶点数量的恒定倍数。


尽管这就是Google的用途,但比起没有更多解释的数学符号而言,它更容易理解。
mLstudent33,

11

时间复杂度O(E+V)不是O(2E+V)因为时间复杂度为n ^ 2 + 2n + 7,而是写为O(n ^ 2)。

因此,O(2E + V)被写为O(E + V)

因为n ^ 2和n之间的差异很重要,但n和2n之间的差异并不重要。


@Am_I_Helpful有人在上面以大哦的符号要求2E ....为什么在时间复杂度上不考虑2。
Dhruvam Gupta 2015年

@Am_I_Helpful刚刚在我的答案上方看到了帖子....有位叫Kehe CAI的用户写道:“我认为每个边缘都被考虑了两次,每个节点都被访问过一次,因此总时间复杂度应为O(2E + V )。” 所以我答应了。。。
Dhruvam Gupta 2015年

我删除我的
否决票

3

我认为每个边缘都被考虑了两次,每个节点都被访问了一次,因此总时间复杂度应为O(2E + V)。


即使我也有同样的感觉。谁能对此进一步解释?
Chaitanya

12
大O分析忽略该常数。O(2E + V)是O(E + V)。
Hemm 2016年

3

对此的直观解释是仅分析一个循环:

  1. 访问顶点-> O(1)
  2. 所有入射边上的for循环-> O(e),其中e是入射在给定顶点v上的边数。

因此,单个循环的总时间为O(1)+ O(e)。现在对每个顶点求和,因为每个顶点都被访问了一次。这给

For every V
=> 

    O(1)
    +

    O(e)

=> O(V) + O(E)

2

简短但简单的说明:

在最坏的情况下,您需要访问所有顶点和边,因此最坏情况下的时间复杂度为O(V + E)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.