我想遍历包含顶点的无向图的每个连接组件。即我想调用每个向量V 一些函数f(V 我)... V ķ其中V 我是含有连接到每个节点中的第i个连接分量的数据的矢量图形。遍历连接的组件
这样做最快的算法是什么?
我的第一个想法是:
- 存放在一个堆所有未访问顶点,然后反复地顶点离堆,使用DFS找到它的连接分量V 我,调用F(V 我)并从堆中删除组件中的所有顶点。
- 查找union-find不相交集合的变体,它不仅支持高效设置联合,而且还可以高效地遍历集合并查找其成员。 (这可能吗?)
我想遍历包含顶点的无向图的每个连接组件。即我想调用每个向量V 一些函数f(V 我)... V ķ其中V 我是含有连接到每个节点中的第i个连接分量的数据的矢量图形。遍历连接的组件
这样做最快的算法是什么?
我的第一个想法是:
运行经典connected components algorithm。通常,这操纵一个disjoint-sets data structure。
创建一个哈希表映射节点到链接的节点列表。
遍历每个节点
a。在不相交集数据结构中找到代表节点
b。如有必要,为散列表中的代表性节点创建链接列表
c。节点添加到与代表性节点
相关的链表这有效地花费线性时间(即Θ(| E | + | V |),预期(根据广泛接受的理解是不相交的集合是有效的线性时间)
现在你有一个哈希表,其条目数是连接组件的数量,每个值都是连接组件中所有节点的链表,现在你可以线性地迭代任何你想要
是的DFS是一个很好的选择为此。但请记住,如果运行递归DFS,给定范围10^7个节点可能会遇到内存问题。因为在麦汁情况下,所有节点将使链,您将需要巨大的规模在堆栈,造成计算器(:d)
尝试这样做:用阶为O
BFS通常用于最短路径问题,但它可以在许多使用其他应用程序,如这一个。这将从队列数据结构的堆中占用空间,通常的递归DFS占用堆栈中的空间。
如果您将图存储为邻接列表,并且顶点由从1
到n-1
的整数表示,那么不需要联合查找或散列表。
我们假设g[v]
是与v
相邻的顶点列表(向量)。此外,让cc
为列表(矢量向量)的列表,其中cc[i]
表示连接组件中的顶点。为了实施目的,当且仅当我们检查DFS
例程中的v
时,我们要使用visited[v] = true
。然后伪代码看起来像这样:
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.
当然DFS是一个办法做到这一点,但它可能取决于如果你想优化这个用于一次性计算,或计算,将经常发生。有了更多的诀窍,你不需要每次重新发现连接的组件。 – AndyG
为什么你需要一堆?使用简单的哈希集,DFS/BFS都可以工作,并且是您可以做到的最优化。 –
我们可以假设您将图存储为邻接列表吗?我们可以假设顶点从0到N-1编号,其中N是顶点的总数? – pkacprzak