00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00027 #ifndef _DFS_H
00028 #define _DFS_H
00029
00030 #include "graph.h"
00031
00032 template <typename Graph, typename DFSVisitor>
00033 class MyDFS {
00034 protected:
00035 typedef typename Graph::Node Node;
00036 typedef typename Graph::Edge Edge;
00037 typedef typename Graph::NodeIterator NodeIterator;
00038 typedef typename Graph::IncidentEdgeIterator EdgeIterator;
00039 protected:
00040
00041
00042 Graph& graph;
00043 DFSVisitor &visitor;
00044
00045 public:
00046 MyDFS(Graph& g, DFSVisitor &v)
00047 : graph(g), visitor(v)
00048 {}
00049
00050 void initialise()
00051 {
00052 NodeIterator nitr = graph.nodes();
00053 while (nitr.hasNext())
00054 {
00055 Node &node = nitr.next();
00056 visitor.markUnvisited(node);
00057 EdgeIterator eitr = graph.incidentEdges(node);
00058 while (eitr.hasNext())
00059 visitor.markUnvisited(*eitr.next());
00060 }
00061
00062
00063
00064
00065 }
00066
00067 virtual ~MyDFS()
00068 {
00069 }
00070
00071 public:
00072
00073
00074 void traverse(Node& v)
00075 {
00076 #ifdef DEBUG
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 #endif
00088
00089 visitor.startVisit(v);
00090
00091 visitor.markVisited(v);
00092 #ifdef DEBUG
00093
00094
00095
00096 #endif
00097 EdgeIterator inEdges = graph.incidentEdges(v);
00098 while (inEdges.hasNext())
00099 {
00100 Edge &e = *inEdges.next();
00101 if (!visitor.isVisited(e))
00102 {
00103
00104 visitor.markVisited(e);
00105
00106 Node *w = e.opposite(v);
00107 #ifdef DEBUG
00108
00109
00110
00111 #endif
00112 if (!visitor.isVisited(*w))
00113 {
00114
00115 visitor.traverseDiscovery(e, v);
00116
00117 if (!visitor.isDone(e, v, *w))
00118
00119 traverse(*w);
00120 }
00121 else
00122 visitor.traverseBack(e, v);
00123 }
00124 }
00125 visitor.finishVisit(v);
00126 #ifdef DEBUG
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 #endif
00139 }
00140 };
00141
00142
00143 class MyDefaultDFSVisitor
00144 {
00145 public:
00146
00147 typedef MyNode Node;
00148 typedef MyEdge Edge;
00149
00150 MyDefaultDFSVisitor()
00151 {}
00152 virtual ~MyDefaultDFSVisitor()
00153 {}
00154 virtual void initialise()
00155 {}
00156
00157
00158 virtual void startVisit(const Node& v)
00159 {}
00160
00161 virtual void finishVisit(const Node& v)
00162 {}
00163
00164 virtual void traverseDiscovery(const Edge& e, const Node& from)
00165 {}
00166
00167 virtual void traverseBack(const Edge& e, const Node& from)
00168 {}
00169
00170
00171
00172 virtual bool isDone(const Edge& e, const Node& from, const Node &to) const
00173 {
00174 return false;
00175 }
00176
00177 void markVisited(Node& v)
00178 {
00179 #ifdef DEBUG
00180
00181 #endif
00182 v.setStatus("visited");
00183 }
00184 void markVisited(Edge& e)
00185 {
00186 #ifdef DEBUG
00187
00188
00189 #endif
00190 e.setStatus("visited");
00191 }
00192 void markUnvisited(Node& v)
00193 {
00194 #ifdef DEBUG
00195
00196 #endif
00197 v.clearStatus("visited");
00198 }
00199 void markUnvisited(Edge& e)
00200 {
00201 #ifdef DEBUG
00202
00203
00204 #endif
00205 e.clearStatus("visited");
00206 }
00207 bool isVisited(Node& v)
00208 {
00209 return v.getStatus("visited");
00210 }
00211 bool isVisited(Edge& e)
00212 {
00213 return e.getStatus("visited");
00214 }
00215 };
00216
00217 class MyComponentsDFSVisitor: public MyDefaultDFSVisitor
00218 {
00219 private:
00220
00221
00222
00223
00224 MyGraph component;
00225 unsigned int size;
00226 public:
00227
00228 MyComponentsDFSVisitor()
00229 :
00230 component(), size(0)
00231 {}
00232 virtual ~MyComponentsDFSVisitor()
00233 {}
00234
00235 virtual void initialise()
00236 {
00237 component.clear();
00238 size = 0;
00239 }
00240
00241
00242 virtual void startVisit(const Node& v)
00243 {
00244 component.addNode(v);
00245 size++;
00246 }
00247
00248 virtual void finishVisit(const Node& v)
00249 {}
00250
00251 virtual void traverseDiscovery(const Edge& e, const Node& from)
00252 {
00253
00254 MyNode &other = *(e.opposite(from));
00255 component.addNode(other);
00256 component.addEdge(e);
00257 }
00258
00259 virtual void traverseBack(const Edge& e, const Node& from)
00260 {
00261 component.addEdge(e);
00262 }
00263
00264
00265 virtual MyGraph &getComponent()
00266 {
00267 return(component);
00268 }
00269
00270 virtual unsigned int getSize()
00271 {
00272 return(size);
00273 }
00274
00275 };
00276
00277 #endif // _DFS_H