private void DepthFirstTraverse(Digraph <T> digraph, T vertex, HashSet <T> visited, HashSet <T> currentPath, Dictionary <T, T> edgeTo)
        {
            currentPath.Add(vertex);
            visited.Add(vertex);
            foreach (var neighbour in digraph.GetNeighbours(vertex))
            {
                if (HasCycle)
                {
                    return;
                }

                if (!visited.Contains(neighbour))
                {
                    edgeTo.Add(neighbour, vertex);
                    DepthFirstTraverse(digraph, neighbour, visited, currentPath, edgeTo);
                }
                else if (currentPath.Contains(neighbour))
                {
                    cycle = new Stack <T>();
                    var current = vertex;
                    while (!current.Equals(neighbour))
                    {
                        cycle.Push(current);
                        current = edgeTo[current];
                    }

                    cycle.Push(neighbour);
                    cycle.Push(vertex);
                }
            }

            currentPath.Remove(vertex);
        }
        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);
        }