迭代连通组件

时间:2016-10-04 12:54:48

标签: algorithm data-structures connected-components

我想迭代包含~10 7 顶点的无向图的每个连通分量。即我想在每个向量上调用一些函数f(V i )V 1 ... V k 其中V i < / sub>是一个向量,包含附加到图的第i个连通分量中每个节点的数据。

执行此操作的最快算法是什么?

我的第一个想法是:

  1. 将所有未访问的顶点存储在堆中,然后重复从堆中取一个顶点,使用DFS查找其连接的组件V i ,调用f(V i )并从堆中删除组件中的所有顶点。
  2. 找到union-find不相交集的变体,它不仅支持高效的集合联合,而且还可以有效地迭代集合并查找其成员。 (这可能吗?)

3 个答案:

答案 0 :(得分:1)

  1. 运行经典connected components algorithm。通常,这会操纵disjoint-sets data structure

  2. 创建一个哈希表,将节点映射到链接的节点列表。

  3. 迭代每个节点

    一个。在disjoint-sets数据结构中找到代表节点

    湾如有必要,为哈希表中的代表节点创建链接列表

    ℃。将节点添加到与代表节点

  4. 关联的链接列表中

    这需要有效的线性时间(即Θ(| E | + | V |),预期(在广泛接受的理解下,不相交集合实际上是线性时间)。

    您现在有一个哈希表,其条目数是连接组件的数量。每个值都是连接组件中所有节点的链接列表。您现在可以线性迭代所需的任何内容。

答案 1 :(得分:0)

是的DFS是一个很好的选择。但请记住,如果运行递归DFS,对于给定范围10 ^ 7个节点,您可能会遇到内存问题。因为在worts案例中所有节点都会形成一个链,你需要大量的堆栈,导致STACKOVERFLOW(:D)

尝试做:

  1. DFS使用堆栈(非递归DFS),订单为O(V + E)或
  2. 简单地使用BFS(考虑简单性和节点数量的最佳选择)订单(V + E)
  3. BFS通常用于最短路径问题,但它可以用于许多其他应用程序,例如这个。这将从堆中获取队列数据结构的空间,其中通常的递归DFS从堆栈中占用空间。

答案 2 :(得分:0)

如果将图形存储为邻接列表,并且顶点由1n-1的整数表示,则不需要union-find或hash表。

假设g[v]是与v相邻的顶点列表(向量)。此外,让cc为列表列表(向量矢量),其中cc[i]表示i-th连通分量中的顶点。出于实现目的,当且仅当我们在visited[v] = true例程中检查v时,我们才会使用DFS。然后伪代码看起来像那样:

dfs(v, current_cc):
   visited[v] = true
   current_cc.append(v)
   for u in g[v]:
      if not visited[u]:
         dfs(u, current_cc)

for v = 0 to n-1:
   visited[i] = false

for v = 0 to n-1:
   if not visited[v]:
      current_cc = []
      dfs(v, current_cc)
      cc.append(current_cc)

//From now, cc[i] is a list of vertices in the i-th connected component, 
//so we can easily iterate and call whatever we want on them.