【问题标题】:Printing(not detecting) cycle with topological sort使用拓扑排序打印(未检测)循环
【发布时间】:2011-12-13 20:05:50
【问题描述】:
这是数据结构和算法分析第 3 版中的一个问题,我们的一项考试中也提出了该问题。
写出一个算法对邻接表表示的图进行拓扑排序,修改
这样算法就会打印出一个循环,如果找到的话。首先,用几句话解释你的想法
句子。 (不要使用深度优先搜索,我们只需要对基本拓扑进行修改
排序。)
答案是:
如果没有一个顶点的入度为 0,我们可以通过向后追踪顶点找到一个循环
正度数;由于回溯上的每个顶点都有一个正入度,我们最终
两次到达一个顶点,循环就找到了。
我不明白追溯部分。“追溯”是什么意思,我想知道这个答案的伪代码会是什么?感谢任何帮助。
【问题讨论】:
标签:
algorithm
graph-algorithm
【解决方案1】:
Kahns 算法的工作原理是选择一个入度为 0 的节点,并删除其所有出边(这可能会产生入度为 0 的新节点)。如果没有找到入度为 0 的节点(并且图现在不是空的),则它包含一个循环。
要打印循环,请从任何地方开始,然后跟随传入的边缘。由于节点的数量是有限的,在某些时候你必须第二次到达一个节点。这是你的循环,要打印它,再运行一次即可。
假设我们的图表是:
a --> b
b --> c, d
c --> b
这个图的反转是
a <--
b <-- a, c
c <-- b
d <-- b
拓扑排序以a 开头,将其删除。 b 现在是 b <-- c
现在我们从任何地方开始,比如d 并向后搜索。
d <-- b <-- c <-- b
既然我们之前见过b,它一定是循环的一部分。要打印,我们再次点击链接并获取b <-- c <-- b。
如果有任何死胡同 - 例如a - 它会在检测到循环之前已经被拓扑排序算法移除。
【解决方案2】:
在完成拓扑排序的过程后(即选择一个入度为0的顶点,将其移除,将其子入度减1,然后重复该过程),如果假设还有一些顶点需要探索并且我们找不到任何入度为 0 的顶点,这意味着我们在由剩余未探索的顶点形成的子图中有一个循环,因为在 DAG 中必须至少有一个入度为 0 的顶点。然后我们拿起从这些剩余的顶点中提取一个顶点,沿着图形追踪直到到达起始顶点,这就是循环。