保持拓扑排序树非循环的最有效方法是什么?

时间:2012-11-17 04:41:14

标签: algorithm

我知道至少有两种方式。

一种方法是每次向非循环树添加边时,遍历必要的顶点。

缺点是随着树变大,遍历过程需要花费越来越多的时间。

另一种方法是被动地检查添加的边是否会产生无限循环。

2 个答案:

答案 0 :(得分:2)

我不确定拓扑排序在哪里,所以这里是你在节点之间创建链接的答案。

一开始假设您只有一组断开连接的节点。在添加链接时,您可以通过链接将节点创建为树。如果您创建一个链接以添加两个以前单独的树,则不会创建循环。如果在已存在于同一树中的两个节点之间添加链接,则会创建一个循环。因此,您可以通过检查要链接的两个节点是否已在同一树中来检查周期。

这是union-find,http://en.wikipedia.org/wiki/Disjoint-set_data_structure中描述了一种有效的方法。

答案 1 :(得分:0)

我对你提到的拓扑排序感到困惑,因为如果你进行拓扑排序,你可以免费进行循环检测,这可以在诸如http://en.wikipedia.org/wiki/Topological_sort之类的地方解释。您还可以从http://en.wikipedia.org/wiki/Connected_component_%28graph_theory%29#Algorithms中获取周期检测。

考虑到这一点,我想知道你是否在尝试在有向图中进行在线循环检测。我想我曾经在一些检测到Unix中用户代码产生的死锁的东西中看到了一些代码 - 它是迭代的并且依赖于一个进程只能等待一个事件的事实。我认为这对应于你的“遍历必要顶点”。

似乎有许多方案依赖于维护拓扑排序顺序。然后,如果您添加的链接与您知道尚未引入循环的顺序一致。问题在于,如果添加与订单不一致的链接,则必须检查周期并维护订单。 http://homepages.ecs.vuw.ac.nz/~djp/files/tr0703.pdf

中描述了三种这样的算法