I have a list of nodes like this
{ a, b , c }
with the dependencies between them defined as
a => { b, c }b => { c }c => { }
The algorithm should return a sorted list so any given node should appear before any of its dependencies For instance, a valid solution would be: {c, b, a}
So far I have this class:
public static class DependencySorter
{
public static ICollection<T> SortDependencies<T>(this IEnumerable<T> nodes) where T : IDependency<T>
{
var set = new HashSet<T>();
foreach (var node in nodes)
{
foreach (var dependency in node.Resolve())
{
set.Add(dependency);
}
}
return set.ToList();
}
public static ICollection<T> Resolve<T>(this T node) where T : IDependency<T>
{
var resolved = new Collection<T>();
ResolveDependenciesRecursive(node, resolved, new List<T>());
return resolved;
}
private static void ResolveDependenciesRecursive<T>(T node, ICollection<T> resolved, ICollection<T> notResolved) where T : IDependency<T>
{
notResolved.Add(node);
foreach (var edge in node.Dependencies.Where(edge => !resolved.Contains(edge)))
{
if (notResolved.Contains(edge))
{
throw new InvalidOperationException($"Circular dependency detected {node} => {edge}");
}
ResolveDependenciesRecursive(edge, resolved, notResolved);
}
resolved.Add(node);
notResolved.Remove(node);
}
}
public interface IDependency<out T>
{
IEnumerable<T> Dependencies { get; }
}
I'm sure that its performance and complexity is really bad.