I have a collection:
List> dependencyHierarchy;
The first item in pair is some object (item) and the
I liked DMM's answer, but it assumes that the input nodes are leaves (which may or may not be what is expected).
I am posting an alternate solution using LINQ that does not make this assumption. In addition, this solution uses yield return
to be able to quickly return the leaves (using e.g. TakeWhile
).
public static IEnumerable TopologicalSort(this IEnumerable nodes,
Func> connected)
{
var elems = nodes.ToDictionary(node => node,
node => new HashSet(connected(node)));
while (elems.Count > 0)
{
var elem = elems.FirstOrDefault(x => x.Value.Count == 0);
if (elem.Key == null)
{
throw new ArgumentException("Cyclic connections are not allowed");
}
elems.Remove(elem.Key);
foreach (var selem in elems)
{
selem.Value.Remove(elem.Key);
}
yield return elem.Key;
}
}