Skip to content

Instantly share code, notes, and snippets.

@yet-another-alexander
Last active July 13, 2018 16:22
Show Gist options
  • Select an option

  • Save yet-another-alexander/0009748f2c0dec1e867e358e5f0d4397 to your computer and use it in GitHub Desktop.

Select an option

Save yet-another-alexander/0009748f2c0dec1e867e358e5f0d4397 to your computer and use it in GitHub Desktop.
Topological Sort algorithm for sorting items based on dependencies
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Application
{
public static class TopologicalSorter
{
/// <summary>
/// Returns a set of items sorted by topological order.
/// </summary>
/// <typeparam name="T">The element type of the sequence.</typeparam>
/// <param name="source">The source.</param>
/// <param name="dependencies">The dependencies.</param>
/// <param name="throwOnCycle">If set to <c>true</c> cyclic dependency is not allowed.</param>
/// <returns>The sorted sequence.</returns>
public static IEnumerable<T> TplgSort<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> dependencies, bool throwOnCycle = false)
{
var sorted = new List<T>();
var visited = new HashSet<T>();
foreach (var item in source)
{
Visit(item, visited, sorted, dependencies, throwOnCycle);
}
return sorted;
}
private static void Visit<T>(T item, HashSet<T> visited, List<T> sorted, Func<T, IEnumerable<T>> 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");
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment