using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Application
{
public static class TopologicalSorter
{
///
/// Returns a set of items sorted by topological order.
///
/// The element type of the sequence.
/// The source.
/// The dependencies.
/// If set to true cyclic dependency is not allowed.
/// The sorted sequence.
public static IEnumerable TplgSort(this IEnumerable source, Func> dependencies, bool throwOnCycle = false)
{
var sorted = new List();
var visited = new HashSet();
foreach (var item in source)
{
Visit(item, visited, sorted, dependencies, throwOnCycle);
}
return sorted;
}
private static void Visit(T item, HashSet visited, List sorted, Func> dependencies, bool throwOnCycle)
{
if (visited.Contains(item) == false)
{
visited.Add(item);
foreach (var dep in dependencies(item))
{
Visit(dep, visited, sorted, dependencies, throwOnCycle);
}
sorted.Add(item);
}
else
{
if (throwOnCycle && sorted.Contains(item) == false)
{
throw new Exception("Cyclic dependency found");
}
}
}
}
}