给出以下列表:
var modules = new List<Module>() {
new Module() { Name = "Audits", Dependencies = new[] { "Logs" } },
new Module() { Name = "Blog", Dependencies = new[] { "Content", "Tags" } },
new Module() { Name = "Content", Dependencies = new[] { "Audits" } },
new Module() { Name = "Logs" },
new Module() { Name = "Tags" }
};
我需要创建一种以编程方式对此列表进行排序的方法,以便最可靠的模块位于顶部。因此,使用上述示例的所需顺序为:
由于“内容”依赖于“审核”,因此首先显示“审核”。但由于“审核”依赖于“日志”,因此“日志”高于“审核”等。 “博客”最后出现,因为它依赖于“内容”和“标签”,因此它们来自上面。
我希望我已经清楚地描述了我的问题。我确信有一些聪明的算法来处理这个问题,并使其尽可能高效,但到目前为止它已经提到了我。如果有人能指出我正确的方向,我会很感激。
由于
答案 0 :(得分:1)
您所描述的问题称为topological sort:给定部分排序,尝试找到一个尊重该排序的线性描述。
解决此问题的典型算法需要O(|V| + |E|)
时间,其中|V|
是顶点数(示例中的模块),|E|
是边数(您的依赖关系)例子)。
链接的维基百科文章还提供了pseudo code。将算法转换为您的示例需要一些预订,但它相对简单。
答案 1 :(得分:0)
最简单的方法是在基于依赖性排序的值之间创建比较函数
static int CompareModules(Module left, Module right) {
if (left.Dependencies.Contains(right.Name)) {
return 1;
}
if (right.Dependencies.Contains(left.Name)) {
return -1;
}
return left.Dependencies.Length - right.Dependencies.Length;
}
然后将此作为List<T>.Sort
modules.Sort(CompareModules);
请注意,此示例假设Dependencies
在没有依赖关系且没有循环依赖关系时为空数组