使用c#查找循环的算法

时间:2014-06-09 17:16:15

标签: c# algorithm data-structures graph-algorithm

我有像

这样的数据
Key  Value
---  -----
A     B
B     E
B     C
C     E
E     D
D     G
F     e

现在,当用户输入A时,我希望输出像

A-B-C-E-D-G

如果用户输入F,则F-E-D-G

我有递归函数,它适用于小于100的键值 如果组合和计数增加,则需要花费太多时间执行

如何使用C#实现这一目标?

2 个答案:

答案 0 :(得分:1)

您拥有的数据定义了Directed Graph (DG)。更传统的表示形式是邻接列表

A -> { B }
B -> { C, E }
C -> { E }
D -> { G }
E -> { D }
F -> { E }
G -> { }

您可以通过对DG运行Depth-First Search (DFS)算法来查找DG中的循环。当且仅当存在back edge时,才存在循环。如果DFS的递归实现向下传递从初始节点到当前节点的路径上访问的顶点列表,则可以更轻松地检索循环。一旦算法检测到后沿,它就会遍历来自源的当前路径,找到后边缘的目标顶点,并将该顶点的边缘作为循环的一部分。

您可以在this question的答案中找到DFS的良好实施。

答案 1 :(得分:0)

如果您的数据变化不大,您可以尝试在后台执行计算并为每个可能的条目维护一组就绪序列 - 在某种字典中。这样您将获得最佳性能。 数据更改后,您可以更新结果字典中的相关路径。 这样,您可以防止对每个请求进行不必要的计算。 您可以使用的另一种策略是尝试按需缓存已计算的结果,因此第一个请求将花费一些时间,但下一次对于已计算的条目,您将不会执行相同的计算,而是返回已计算的结果。 同样,所有这些都将通过相对静态的初始数据改善性能。 如果您的初始集快速变化,您应该考虑某种数据结构,它将帮助您避免递归,或者至少最小化递归堆栈的深度。