*** depth_first_search.hpp.orig Mon Aug 19 18:16:50 2002 --- depth_first_search.hpp Sun Jun 22 15:17:30 2003 *************** *** 27,33 **** #ifndef BOOST_GRAPH_RECURSIVE_DFS_HPP #define BOOST_GRAPH_RECURSIVE_DFS_HPP - #include #include #include #include --- 27,32 ---- *************** *** 35,40 **** --- 34,40 ---- #include #include #include + #include namespace boost { *************** *** 61,66 **** --- 61,138 ---- namespace detail { + #ifdef BOOST_NONRECURSIVE_DFS + + // Nonrecursive implementation of depth_first_visit_impl submitted by + // Bruce Barr, schmoost yahoo.com, May/June 2003. + + // If the vertex u and the iterators ei and ei_end are thought of as the + // context of the algorithm, each push and pop from the stack could + // be thought of as a context shift. + // Each pass through "while (ei != ei_end)" may refer to the out-edges of + // an entirely different vertex, because the context of the algorithm + // shifts every time a white adjacent vertex is discovered. + // The corresponding context shift back from the adjacent vertex occurs + // after all of its out-edges have been examined. + + template + void depth_first_visit_impl + (const IncidenceGraph& g, + typename graph_traits::vertex_descriptor u, + DFSVisitor& vis, + ColorMap color) + { + function_requires >(); + function_requires >(); + typedef typename graph_traits::vertex_descriptor Vertex; + function_requires< ReadWritePropertyMapConcept >(); + typedef typename property_traits::value_type ColorValue; + function_requires< ColorValueConcept >(); + typedef color_traits Color; + typedef typename graph_traits::out_edge_iterator Iter; + typedef std::pair > VertexInfo; + + Iter ei, ei_end; + std::vector stack; + + // Possible optimization for vector + //stack.reserve(num_vertices(g)); + + put(color, u, Color::gray()); + vis.discover_vertex(u, g); + tie(ei, ei_end) = out_edges(u, g); + stack.push_back(std::make_pair(u, std::make_pair(ei, ei_end))); + while (!stack.empty()) { + VertexInfo& back = stack.back(); + u = back.first; + tie(ei, ei_end) = back.second; + stack.pop_back(); + while (ei != ei_end) { + Vertex v = target(*ei, g); + vis.examine_edge(*ei, g); + ColorValue v_color = get(color, v); + if (v_color == Color::white()) { + vis.tree_edge(*ei, g); + stack.push_back(std::make_pair(u, std::make_pair(++ei, ei_end))); + u = v; + put(color, u, Color::gray()); + vis.discover_vertex(u, g); + tie(ei, ei_end) = out_edges(u, g); + } else if (v_color == Color::gray()) { + vis.back_edge(*ei, g); + ++ei; + } else { + vis.forward_or_cross_edge(*ei, g); + ++ei; + } + } + put(color, u, Color::black()); + vis.finish_vertex(u, g); + } + } + + #else // BOOST_NONRECURSIVE_DFS not defined + template void depth_first_visit_impl (const IncidenceGraph& g, *************** *** 88,93 **** --- 160,168 ---- } put(color, u, Color::black()); vis.finish_vertex(u, g); } + + #endif + } // namespace detail template