private void DepthFirstTraverse(Digraph <T> digraph, T vertex, HashSet <T> visited)
        {
            preOrder.Enqueue(vertex);

            visited.Add(vertex);
            foreach (var neighbour in digraph.GetNeighbours(vertex))
            {
                if (!visited.Contains(neighbour))
                {
                    DepthFirstTraverse(digraph, neighbour, visited);
                }
            }

            postOrder.Enqueue(vertex);
            reversePostOrder.Push(vertex);
        }
        public DirectedCycle(Digraph <T> digraph)
        {
            if (digraph == null)
            {
                throw new ArgumentNullException(nameof(digraph));
            }

            var currentPath = new HashSet <T>();
            var edgeTo      = new Dictionary <T, T>();
            var visited     = new HashSet <T>();

            foreach (var vertex in digraph.Vertices)
            {
                if (!visited.Contains(vertex))
                {
                    DepthFirstTraverse(digraph, vertex, visited, currentPath, edgeTo);
                }
            }
        }
        public DepthFirstOrder(Digraph <T> digraph)
        {
            if (digraph == null)
            {
                throw new ArgumentNullException(nameof(digraph));
            }

            postOrder        = new Queue <T>(digraph.VertexNumber);
            preOrder         = new Queue <T>(digraph.VertexNumber);
            reversePostOrder = new Stack <T>(digraph.VertexNumber);

            var visited = new HashSet <T>();

            foreach (var vertex in digraph.Vertices)
            {
                if (!visited.Contains(vertex))
                {
                    DepthFirstTraverse(digraph, vertex, visited);
                }
            }
        }
        public int[] FindOrder(int numCourses, int[][] prerequisites)
        {
            var courses = new List <int>();

            if (prerequisites != null)
            {
                var digraph = new Digraph <int>();
                foreach (var prerequisite in prerequisites)
                {
                    digraph.AddEdge(prerequisite[1], prerequisite[0]);
                }

                var order = new Topological <int>(digraph).Order;
                if (order == null && prerequisites.Length > 0)
                {
                    return(new int[0]);
                }

                if (order != null)
                {
                    foreach (var course in order)
                    {
                        courses.Add(course);
                    }
                }
            }

            while (numCourses-- > 0)
            {
                if (!courses.Contains(numCourses))
                {
                    courses.Add(numCourses);
                }
            }

            return(courses.ToArray());
        }