Algorithm 使用三色算法进行周期检测与使用集合进行周期检测相比,使用其中一种算法比使用另一种算法有什么优势?
有两种看似相似的方法可以检测图形中的循环:Algorithm 使用三色算法进行周期检测与使用集合进行周期检测相比,使用其中一种算法比使用另一种算法有什么优势?,algorithm,graph,depth-first-search,Algorithm,Graph,Depth First Search,有两种看似相似的方法可以检测图形中的循环: 以DFS样式遍历图形,假设所有节点在您第一次访问它们之前都是白色的,使它们变为灰色。在节点上完成所有处理后,将其变为黑色。如果你访问过灰色节点,你就知道你有一个循环 遍历图、DFS样式,并保留一个集合,其中包含DFS堆栈中当前的所有节点(仅用于性能目的)。每次访问节点时,都会将其添加到S中,每次处理完节点后,都会将其从S中删除。如果在任何时候尝试访问已在S中的节点,则存在一个循环 选择一个替代方案比另一个方案有实际优势吗?我可能错过了某种权衡?或者使用
感谢这两个在概念上是等价的:集合
S
完全包含灰色节点,其他方面的算法是相同的
然而,在实践中,存在着微妙的差异:
- 如果set
是基于哈希的实现,那么节点必须是可哈希的。如果散列函数设计不当,或者数据被逆向选择,那么性能可能会受到影响S
- 如果set
是基于树的实现,则节点必须具有可比性。此外,您不再具有(摊销)常数时间集查找S
- 如果使用颜色,则节点必须有一个“颜色”字段,该字段不能用于其他目的。然而,这提供了最快的“集合查找”,因为它只是一个查找/比较
- 如果图形是定向的或断开连接的,则必须多次使用DFS(从所有白色节点)。跟踪节点是否已被访问需要第二个集合,因为第一个集合在DFS结束时始终为空。因为实际上有3个节点“状态”,所以需要2组来存储该信息
color
字段不是一个选项,那么使用集合是一个不错的选择。如果节点当前实现为int
s或String
s(与可能添加字段的Node
类相反),那么set方法将更易于编码,因为可以避免更改节点的表示形式