/*** * Computes one topological sorting of a DAG (Directed Acyclic Graph). * This class depends on the CyclesDetector static class. */ using System; using System.Collections.Generic; using DataStructures.Graphs; namespace Algorithms.Graphs { public static class TopologicalSorter { /// <summary> /// Private recursive helper. /// </summary> private static void _topoSortHelper<T>(IGraph<T> graph, T source, ref DataStructures.Lists.Stack<T> topoSortStack, ref HashSet<T> visited) where T : IComparable<T> { visited.Add(source); foreach (var adjacent in graph.Neighbours(source)) if (!visited.Contains(adjacent)) _topoSortHelper<T>(graph, adjacent, ref topoSortStack, ref visited); topoSortStack.Push(source); } /// <summary> /// The Topological Sorting algorithm /// </summary> public static IEnumerable<T> Sort<T>(IGraph<T> Graph) where T : IComparable<T> { // If the graph is either null or is not a DAG, throw exception. if (Graph == null) throw new ArgumentNullException(); if (!Graph.IsDirected || CyclesDetector.IsCyclic<T>(Graph)) throw new Exception("The graph is not a DAG."); var visited = new HashSet<T>(); var topoSortStack = new DataStructures.Lists.Stack<T>(); foreach (var vertex in Graph.Vertices) if (!visited.Contains(vertex)) _topoSortHelper<T>(Graph, vertex, ref topoSortStack, ref visited); return topoSortStack; } } }