问题:
定向和无向图的DFS复杂度是否不同?
如果是,则有向图复杂度为O(V + E),无向图复杂度为O(E)?,其中E为边,V为顶点?
如果是,那么以下是评论 - 有向图正确的O(V + E)复杂度的解释?
/*
* Although this piece looks like it is O(V * E), it is actually O(V + E)
* This is because, for each node, we dont do dfs across the full tree.
* ie
* A -> C
* |
* V
* B
* Here A has a directed edge to B and C.
* This means that when 'Node' == A then 'dfs' code would cost O(E)
* But when the 'node' == B then 'dfs' would cost O(1), since B does not have any outgoing edge
* and when the 'node' == C then 'dfs' would cost O(1), since C does not have any outgoing edge
* This O(E + 1 + 1) = O(E)
* And O(A + B + C) = O(V)
*
*/
for (T node : graph) {
if (dfs(graph, node, visitedNodes, completedNodes)) return true;
}
答案 0 :(得分:0)
简而言之,有向图和无向图的DFS复杂度应该相同。而且看起来你对复杂性的论证只适用于某个特定的图形,我在下面提供了一个更为一般的参数供你参考。
给定图 G =(V,E),我们用 n = | V | 表示图的顶点数, m = | E | 图表的边数。 DFS算法递归地给出如下:
Mark all vertices as unexplored
DFS(graph G, start vertex s)
- Mark s as explored
- For every edge (s, v):
- If v is unexplored
- DFS(G, v)
它实际上取决于您用于实现图形的基础数据结构。
邻接矩阵是 n n 矩阵,其中 a ij (即 i -th行的条目和 j -th)表示来自顶点数字 >我到顶点 j 。在这种情况下,DFS的复杂性是 O(n 2 )。
邻接列表是每个顶点的 n 无序列表的集合,每个列表代表其顶点的邻居集。在这种情况下,DFS的复杂性是 O(n + m) (对于有向图和无向图)。
首先考虑使用邻接列表来表示图形,其中顶点 v 的列表由指向相邻顶点的指针组成。设 m v 表示与顶点 v 相邻的边数。因此,调用DFS(G, v)
所需的工作量为1 + m v (将 v 标记为已探查,然后循环在 m v 边缘)。观察从任意顶点 s 开始,DFS算法在每个顶点最多上递归调用一次(当顶点未被探测时),因此所需的总工作量为< em>最多:
Σv∈V(1 + m v )= | V | +Σv∈V m v
在定向图中,我们有Σv∈V m v = | E | ,而在无向图中,我们有Σv∈V m v = 2 | E | (这是因为(u,v)和(v,u)被视为无向图中的相同边)。在这两种情况下,所需的总工作量为 O(| V | + | E |)= O(n + m)。
如果我们使用邻接矩阵来表示图形,则对于每个顶点,DFS算法也将以递归方式最多一次调用。但是,如果我们想在这种情况下遍历顶点 v 的所有传出边缘,我们必须遍历与对应的行上的所有条目邻接矩阵中的v 以查找所有非零条目,这总共需要 n = | V | 扫描。因此,在这种情况下,DFS所需的总工作量为 O(| V | 2 )= O(n 2 )。