在图表中查找已连接的组件

aba*_*rek 41 algorithm graph

如果我有一个无向图(实现为顶点列表),我怎样才能找到它的连通组件?我怎样才能使用快速联合?

Ase*_*yal 39

使用深度优先搜索(DFS)将所有连接的组件标记为已访问:

dfs(node u)
  for each node v connected to u :
    if v is not visited :
      visited[v] = true
      dfs(v)


for each node u:
  if u is not visited :
    visited[u] = true
    connected_component += 1
    dfs(u)
Run Code Online (Sandbox Code Playgroud)

最好的方法是使用这种简单的方法,即线性时间O(n).
既然你问过union-find算法:

for each node parent[node] = node  

for each node u :
   for each node v connected to u :  
       if findset(u)!=findset(v) :
           union(u,v)  

**I assume you know about how findset and union works **  
for each node if (parent[node] == node)  
    connected_component += 1
Run Code Online (Sandbox Code Playgroud)

  • 有没有理由在bfs上使用dfs? (8认同)
  • @ThunderWiring我不确定我理解.什么阻止我们从其中一个未访问/未发现的节点运行BFS?在DFS的定义中似乎没有必要为图中的每个未发现的节点运行它.如果在每个未发现的节点上运行BFS或DFS,您将获得连接组件的林. (3认同)
  • @Will:是的,因为BFS从你最初选择的节点"X"开始覆盖"层"中的图形,意味着如果某个节点"Y"无法从"X"到达,那么BFS将不会访问它.虽然在这种情况下DFS会这样做,为什么?因为当你从"X"覆盖所有可到达的节点并且仍然有一些未访问的节点时,DFS将从其中一个节点重新开始,因此DFS为您提供森林,而BFS为一棵树. (2认同)
  • @ThunderWiring 关于您声称 Asem 的算法不正确的说法:您不需要明确的基本情况(您称之为“停止条件”)来退出递归,因为 for 循环(上面的第 2 行)最终将终止(因为给定的节点连接到它的节点数量是有限的)。一旦所有未访问的邻居都被 `dfs`'d,顶级的 `dfs` 调用将全部触底。 (2认同)
  • @ThunderWiring 我不同意你的说法“如果某个节点 Y 无法从 X 到达,那么 BFS 将不会访问它。而在这种情况下 DFS 会......”如果一个节点无法从 X 到达 BFS或者 DFS 可以给你那个节点,如果你是从 X 开始的。你能举例说明你在说什么吗? (2认同)