// -*- c++ -*- #ifndef HUGO_BFS_ITERATOR_H #define HUGO_BFS_ITERATOR_H #include #include #include namespace hugo { template */ > class BfsIterator { protected: typedef typename Graph::Node Node; typedef typename Graph::OutEdgeIt OutEdgeIt; const Graph* graph; std::queue bfs_queue; ReachedMap& reached; bool b_node_newly_reached; OutEdgeIt actual_edge; bool own_reached_map; public: BfsIterator(const Graph& _graph, ReachedMap& _reached) : graph(&_graph), reached(_reached), own_reached_map(false) { } BfsIterator(const Graph& _graph) : graph(&_graph), reached(*(new ReachedMap(*graph /*, false*/))), own_reached_map(true) { } ~BfsIterator() { if (own_reached_map) delete &reached; } void pushAndSetReached(Node s) { reached.set(s, true); if (bfs_queue.empty()) { bfs_queue.push(s); graph->first(actual_edge, s); if (graph->valid(actual_edge)) { Node w=graph->bNode(actual_edge); if (!reached[w]) { bfs_queue.push(w); reached.set(w, true); b_node_newly_reached=true; } else { b_node_newly_reached=false; } } } else { bfs_queue.push(s); } } BfsIterator& operator++() { if (graph->valid(actual_edge)) { graph->next(actual_edge); if (graph->valid(actual_edge)) { Node w=graph->bNode(actual_edge); if (!reached[w]) { bfs_queue.push(w); reached.set(w, true); b_node_newly_reached=true; } else { b_node_newly_reached=false; } } } else { bfs_queue.pop(); if (!bfs_queue.empty()) { graph->first(actual_edge, bfs_queue.front()); if (graph->valid(actual_edge)) { Node w=graph->bNode(actual_edge); if (!reached[w]) { bfs_queue.push(w); reached.set(w, true); b_node_newly_reached=true; } else { b_node_newly_reached=false; } } } } return *this; } bool finished() const { return bfs_queue.empty(); } operator OutEdgeIt () const { return actual_edge; } bool isBNodeNewlyReached() const { return b_node_newly_reached; } bool isANodeExamined() const { return !(graph->valid(actual_edge)); } Node aNode() const { return bfs_queue.front(); } Node bNode() const { return graph->bNode(actual_edge); } const ReachedMap& getReachedMap() const { return reached; } const std::queue& getBfsQueue() const { return bfs_queue; } }; template */ > class DfsIterator { protected: typedef typename Graph::Node Node; typedef typename Graph::OutEdgeIt OutEdgeIt; const Graph* graph; std::stack dfs_stack; bool b_node_newly_reached; OutEdgeIt actual_edge; Node actual_node; ReachedMap& reached; bool own_reached_map; public: DfsIterator(const Graph& _graph, ReachedMap& _reached) : graph(&_graph), reached(_reached), own_reached_map(false) { } DfsIterator(const Graph& _graph) : graph(&_graph), reached(*(new ReachedMap(*graph /*, false*/))), own_reached_map(true) { } ~DfsIterator() { if (own_reached_map) delete &reached; } void pushAndSetReached(Node s) { actual_node=s; reached.set(s, true); OutEdgeIt e; graph->first(e, s); dfs_stack.push(e); } DfsIterator& operator++() { actual_edge=dfs_stack.top(); //actual_node=G.aNode(actual_edge); if (graph->valid(actual_edge)/*.valid()*/) { Node w=graph->bNode(actual_edge); actual_node=w; if (!reached[w]) { OutEdgeIt e; graph->first(e, w); dfs_stack.push(e); reached.set(w, true); b_node_newly_reached=true; } else { actual_node=graph->aNode(actual_edge); graph->next(dfs_stack.top()); b_node_newly_reached=false; } } else { //actual_node=G.aNode(dfs_stack.top()); dfs_stack.pop(); } return *this; } bool finished() const { return dfs_stack.empty(); } operator OutEdgeIt () const { return actual_edge; } bool isBNodeNewlyReached() const { return b_node_newly_reached; } bool isANodeExamined() const { return !(graph->valid(actual_edge)); } Node aNode() const { return actual_node; /*FIXME*/} Node bNode() const { return graph->bNode(actual_edge); } const ReachedMap& getReachedMap() const { return reached; } const std::stack& getDfsStack() const { return dfs_stack; } }; } // namespace hugo #endif //HUGO_BFS_ITERATOR_H