订单列表依赖关系

时间:2014-02-06 16:52:50

标签: c# sorting compare

给出以下列表:

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" }
};

我需要创建一种以编程方式对此列表进行排序的方法,以便最可靠的模块位于顶部。因此,使用上述示例的所需顺序为:

  1. 日志
  2. 审核
  3. 内容
  4. 标签
  5. 博客
  6. 由于“内容”依赖于“审核”,因此首先显示“审核”。但由于“审核”依赖于“日志”,因此“日志”高于“审核”等。 “博客”最后出现,因为它依赖于“内容”和“标签”,因此它们来自上面。

    我希望我已经清楚地描述了我的问题。我确信有一些聪明的算法来处理这个问题,并使其尽可能高效,但到目前为止它已经提到了我。如果有人能指出我正确的方向,我会很感激。

    由于

2 个答案:

答案 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在没有依赖关系且没有循环依赖关系时为空数组