/// <summary>Iterative deph-first-search algorithm.</summary> /// <param name="graph">a graph</param> /// <param name="strategy">a searching strategy</param> /// <param name="roots">starting vertices</param> /// <returns>enumerable of visited vertices</returns> public static IEnumerable <Vertex <TVertexId> > DfsIterative <TVertexId, TVertexProperty, TEdgeProperty>( this IGraph <TVertexId, TVertexProperty, TEdgeProperty> graph, IDfsStrategy <TVertexId> strategy, IEnumerable <Vertex <TVertexId> > roots) { var reached = new Dictionary <Vertex <TVertexId>, int>(); var vertexStack = new Stack <Vertex <TVertexId> >(); int iteration = 1; foreach (Vertex <TVertexId> root in roots) { if (!reached.ContainsKey(root)) { strategy.ForRoot(root); vertexStack.Push(root); while (vertexStack.Count != 0) { Vertex <TVertexId> vertex = vertexStack.Pop(); if (!reached.ContainsKey(vertex)) { reached[vertex] = iteration; strategy.OnEntry(vertex); foreach (Vertex <TVertexId> neighbour in graph.GetNeighbours(vertex)) { if (!reached.ContainsKey(neighbour)) { strategy.OnNextVertex(vertex, neighbour); vertexStack.Push(neighbour); } else if (reached[neighbour] == iteration) { strategy.OnEdgeToVisited(vertex, neighbour); } } strategy.OnExit(vertex); reached[root] = -iteration; } } ++iteration; } } return(reached.Keys); }
/// <summary>Recursive deph-first-search algorithm.</summary> /// <param name="graph">a graph</param> /// <param name="strategy">a searching strategy</param> /// <param name="roots">starting vertices</param> /// <returns>enumerable of visited vertices</returns> public static IEnumerable <Vertex <TVertexId> > DfsRecursive <TVertexId, TVertexProperty, TEdgeProperty>( this IGraph <TVertexId, TVertexProperty, TEdgeProperty> graph, IDfsStrategy <TVertexId> strategy, IEnumerable <Vertex <TVertexId> > roots) { var state = new DfsRecursiveState <TVertexId>(); foreach (Vertex <TVertexId> root in roots) { if (!state.reached.ContainsKey(root)) { strategy.ForRoot(root); state.vertex = root; graph.dfsRecursiveStep(strategy, state); ++state.iteration; } } return(state.reached.Keys); }