这两种看似相似的方法可以检测图表中的循环:
遍历图表,DFS样式,假设所有节点都是白色的,直到您第一次访问它们,使它们变为灰色。在节点上完成所有处理后,将其变为黑色。如果您访问过灰色节点,则表示您有一个循环。
遍历图形,DFS样式,并保留一个集合S,其中包含当前DFS堆栈中的所有节点(仅用于性能目的)。每次访问节点时,都会将其添加到S,每次完成节点后,都会将其从S中删除。如果在任何时候您尝试访问已在S中的节点,则存在循环。
选择其中一种替代方案是否有任何实际优势?我可能会失去一些权衡吗?或者使用一个或另一个导致完全相同?
由于
答案 0 :(得分:3)
这两个在概念上是等价的:集合S
恰好包含灰色节点,否则算法是相同的。
然而,在实践中,存在细微差别:
S
是基于散列的实现,则节点必须是可散列的。如果散列函数的设计很差,或者数据是对抗性的,那么性能就会受到影响。S
是基于树的实现,则节点必须具有可比性。此外,您不再具有(分期)常量时间设置查找。在性能关键的情况下,颜色方法将具有较小的线性运行时常数因子。但是,如果向节点添加color
字段不是一个选项,那么使用集合是一个很好的选择。如果节点当前实现为int
或String
s(而不是Node
类,可以添加字段),那么设置方法将更容易编码,因为您可以避免改变节点的表示。