| 1 | // -*-mode: c++; -*- | 
|---|
| 2 | #ifndef __OLDGRAPH_H_ | 
|---|
| 3 | #define __OLDGRAPH_H_ | 
|---|
| 4 |  | 
|---|
| 5 | #include <stdio.h> | 
|---|
| 6 |  | 
|---|
| 7 | //#include <new> | 
|---|
| 8 |  | 
|---|
| 9 | #define INVALID -1 | 
|---|
| 10 | #define FREE_NODE INVALID | 
|---|
| 11 |  | 
|---|
| 12 | #define EDGE_BLOCK_SIZE 100 | 
|---|
| 13 | #define INIT_NODES_SIZE 10 | 
|---|
| 14 | #define INIT_EDGES_BLOCK_MAX 10 | 
|---|
| 15 |  | 
|---|
| 16 | #define foreachNode(n,G) for((n)=(G).FirstNode();(n)!=INVALID;(n)=(G).NextNode(n)) | 
|---|
| 17 | #define foreachIn(e,G,n)  for((e)=(G).FirstIn(n) ;(e);(e)=(G).NextIn(e) ) | 
|---|
| 18 | #define foreachOut(e,G,n) for((e)=(G).FirstOut(n);(e);(e)=(G).NextOut(e)) | 
|---|
| 19 | #define foreachEdge(e,G,n) for((e)=(G).FirstEdge(n);(e);(e)=(G).NextEdge((n),(e))) | 
|---|
| 20 |  | 
|---|
| 21 | struct EdgeIndex { int block,index; }; | 
|---|
| 22 |  | 
|---|
| 23 | extern EdgeIndex InvalidIndex; | 
|---|
| 24 |  | 
|---|
| 25 | class EdgeCorp; | 
|---|
| 26 | typedef EdgeCorp *EdgePoint; | 
|---|
| 27 |  | 
|---|
| 28 | class EdgeCorp { | 
|---|
| 29 |  public: | 
|---|
| 30 |   int from,to;      //from==INVALID <=> this is a free edge. | 
|---|
| 31 |   EdgePoint previn,nextin,prevout,nextout; | 
|---|
| 32 |   EdgeIndex index; | 
|---|
| 33 |  | 
|---|
| 34 |   int From() { return from; } | 
|---|
| 35 |   int To() { return to; } | 
|---|
| 36 |   EdgePoint NextIn() { return nextin; } | 
|---|
| 37 |   EdgePoint NextOut() { return nextout; } | 
|---|
| 38 | }; | 
|---|
| 39 |  | 
|---|
| 40 | inline int From(EdgePoint e) { return e->from; } | 
|---|
| 41 | inline int To(EdgePoint e) { return e->to; } | 
|---|
| 42 | inline EdgePoint NextIn(EdgePoint e) { return e->nextin; } | 
|---|
| 43 | inline EdgePoint NextOut(EdgePoint e) { return e->nextout; } | 
|---|
| 44 |  | 
|---|
| 45 |  | 
|---|
| 46 | ////////////////////////////////////////////////////////////////////// | 
|---|
| 47 | //   OLDGRAPH TEMPLATE | 
|---|
| 48 | ////////////////////////////////////////////////////////////////////// | 
|---|
| 49 | // Copy Constructor should be provided for N | 
|---|
| 50 |  | 
|---|
| 51 | //class Graph; | 
|---|
| 52 | //class Graph::NodeIterator; //Nem megy. Disznosag! | 
|---|
| 53 | template <class N, class E> class OldGraph | 
|---|
| 54 | { | 
|---|
| 55 |  | 
|---|
| 56 |   //  friend class NEGRO::Graph::NodeIterator; //Nem megy. Disznosag! | 
|---|
| 57 |  | 
|---|
| 58 |  | 
|---|
| 59 |   class nodes_t; | 
|---|
| 60 |   friend class OldGraph::nodes_t; | 
|---|
| 61 |   class edge_block; | 
|---|
| 62 |   friend class OldGraph::edge_block; | 
|---|
| 63 |    | 
|---|
| 64 |   class edge_t : public EdgeCorp { | 
|---|
| 65 |   public: | 
|---|
| 66 |     //edge_t *previn,*nextin,*prevout,*nextout; | 
|---|
| 67 |     union { | 
|---|
| 68 |       int _align; | 
|---|
| 69 |       char data[sizeof(E)]; | 
|---|
| 70 |     }; | 
|---|
| 71 |   }; | 
|---|
| 72 |  | 
|---|
| 73 |   class nodes_t { | 
|---|
| 74 |   public: | 
|---|
| 75 |     union { | 
|---|
| 76 |       int _align; | 
|---|
| 77 |       char data[sizeof(N)]; | 
|---|
| 78 |     }; | 
|---|
| 79 |     int indeg,outdeg;           // indeg==FREE_NODE <=> this node is free. | 
|---|
| 80 |     EdgePoint firstin, firstout; | 
|---|
| 81 |     int prev,next; | 
|---|
| 82 |  | 
|---|
| 83 |     void Copy(nodes_t &n)  | 
|---|
| 84 |     { | 
|---|
| 85 |       indeg = n.indeg; outdeg = n.outdeg; | 
|---|
| 86 |       firstin = n.firstin; firstout = n.firstout; | 
|---|
| 87 |       prev = n.prev; next = n.next; | 
|---|
| 88 |       if(n.indeg!=FREE_NODE) new(data) N(*(N*)(n.data)); | 
|---|
| 89 |       //      if(n.indeg!=FREE_NODE) { | 
|---|
| 90 |       //        new(data) N; | 
|---|
| 91 |       //        (*(N*)(data))=(*(N*)(n.data)); | 
|---|
| 92 |       //      } | 
|---|
| 93 |     } | 
|---|
| 94 |      | 
|---|
| 95 |   } *nodes; | 
|---|
| 96 |   int nodenum, nodes_size; | 
|---|
| 97 |   int firstnode, freenodes; | 
|---|
| 98 |   class edge_block { | 
|---|
| 99 |   public: | 
|---|
| 100 |     //edge_block *next; | 
|---|
| 101 |     //    char fields[sizeof(edge_t)*EDGE_BLOCK_SIZE]; | 
|---|
| 102 |     edge_t fields[EDGE_BLOCK_SIZE];     | 
|---|
| 103 |   } **edges; | 
|---|
| 104 |   int edge_block_num,edge_block_max; | 
|---|
| 105 |   EdgePoint freeedges; | 
|---|
| 106 |  | 
|---|
| 107 |   void setup(int nosi = INIT_NODES_SIZE); | 
|---|
| 108 |   void destroy(); | 
|---|
| 109 |   void inc_nodes_size(int n); | 
|---|
| 110 |    | 
|---|
| 111 |  public: | 
|---|
| 112 |   int NodeNum() {return nodenum;}; | 
|---|
| 113 |   int EdgeNum(); | 
|---|
| 114 |   int MaxNode() const {return nodes_size;}; | 
|---|
| 115 |   int FirstNode() const {return firstnode;}; | 
|---|
| 116 |   int NextNode(int n) const {return nodes[n].next;}; | 
|---|
| 117 |   int PrevNode(int n) const {return nodes[n].prev;}; | 
|---|
| 118 |   N& operator()(int n) const {return *(N*)(nodes[n].data);}; | 
|---|
| 119 |   N& Data      (int n) const {return *(N*)(nodes[n].data);}; | 
|---|
| 120 |   int AddNode(); | 
|---|
| 121 |   void AddNodeBlock(int n) const {for(int i=0;i<n;i++) AddNode();} | 
|---|
| 122 |   int AddNode(int n); | 
|---|
| 123 |   void Delete(int n); | 
|---|
| 124 |   int isaNode(int n) const  | 
|---|
| 125 |         {return n>=0&&n<nodes_size&&nodes[n].indeg!=FREE_NODE;}; | 
|---|
| 126 |    | 
|---|
| 127 |   int InDeg(int n) const {return nodes[n].indeg;}; | 
|---|
| 128 |   int OutDeg(int n) const {return nodes[n].outdeg;}; | 
|---|
| 129 |   EdgePoint FirstIn(int n) const {return nodes[n].firstin;}; | 
|---|
| 130 |   EdgePoint FirstOut(int n) const {return nodes[n].firstout;}; | 
|---|
| 131 |  | 
|---|
| 132 |   E& operator()(EdgePoint e) const {return *(E*)(((edge_t*)e)->data);}; | 
|---|
| 133 |   E& Data      (EdgePoint e) const {return *(E*)(((edge_t*)e)->data);}; | 
|---|
| 134 |   int From(EdgePoint e) const {return e->from;}; | 
|---|
| 135 |   int To(EdgePoint e) const {return e->to;}; | 
|---|
| 136 |   EdgePoint NextIn(EdgePoint e) const  | 
|---|
| 137 |     {return e->nextin;}; | 
|---|
| 138 |   EdgePoint NextOut(EdgePoint e)const  | 
|---|
| 139 |     {return e->nextout;}; | 
|---|
| 140 |   EdgePoint AddEdge(int f, int t); | 
|---|
| 141 |   void Delete(EdgePoint e); | 
|---|
| 142 |   EdgePoint Edge(int f,int t); | 
|---|
| 143 |   //  EdgePoint Edge(E &d) | 
|---|
| 144 |   //    {return (EdgePoint)(((char*)&d)-(char*)&(((edge_t*)NULL)->data));}; | 
|---|
| 145 |   E& operator()(int f, int t) const {return *(E*)(((edge_t*)Edge(f,t))->data);}; | 
|---|
| 146 |   E& Data(int f, int t) const {return *(E*)(((edge_t*)Edge(f,t))->data);}; | 
|---|
| 147 |   void Delete(int f, int t) {Delete(Edge(f,t));}; | 
|---|
| 148 |   void Reverse(EdgePoint e); | 
|---|
| 149 |  | 
|---|
| 150 |   // Functions for EdgeIndex | 
|---|
| 151 |    | 
|---|
| 152 |   EdgePoint Edge(EdgeIndex i) const  | 
|---|
| 153 |     { return (EdgePoint)(edges[i.block]->fields+i.index);}; | 
|---|
| 154 |   EdgeIndex Index(EdgePoint e) const { return e->index;}; | 
|---|
| 155 |   EdgeIndex Index(int f, int t) const { EdgePoint e; return Edge(f,t)->index; } | 
|---|
| 156 |   void Delete(EdgeIndex i) { Delete(Edge(i));}; | 
|---|
| 157 |   E& operator()(EdgeIndex i) const  | 
|---|
| 158 |      {return *(E*)(edges[i.block]->fields[i.index].data);}; | 
|---|
| 159 |   E& Data(EdgeIndex i) const  | 
|---|
| 160 |      {return *(E*)(edges[i.block]->fields[i.index].data);}; | 
|---|
| 161 |   EdgePoint AddEdge(int f, int t,EdgeIndex in); | 
|---|
| 162 |    | 
|---|
| 163 |  | 
|---|
| 164 |    | 
|---|
| 165 |   // Operators for symmetric graphs: | 
|---|
| 166 |  | 
|---|
| 167 |   EdgePoint FirstEdge(int n) const  | 
|---|
| 168 |     { return (EdgePoint)(FirstIn(n)?FirstIn(n):FirstOut(n));}; | 
|---|
| 169 |   EdgePoint NextEdge(int n,EdgePoint e) const  | 
|---|
| 170 |     { return From(e)==n?NextOut(e):(NextIn(e)?NextIn(e):FirstOut(n)); }; | 
|---|
| 171 |   int Opposite(EdgePoint e,int n) const  | 
|---|
| 172 |     { return From(e)+To(e)-n; }; | 
|---|
| 173 |    | 
|---|
| 174 |   // Initializers, destructors | 
|---|
| 175 |         | 
|---|
| 176 |   OldGraph() {setup();}; | 
|---|
| 177 |   OldGraph(int nosi) {setup(nosi);}; | 
|---|
| 178 |   OldGraph(OldGraph<N,E> &H) {setup();operator=(H);}; | 
|---|
| 179 |   ~OldGraph() {destroy();};   | 
|---|
| 180 |   void Clean(int nosi = INIT_NODES_SIZE) {destroy();setup(nosi);}; | 
|---|
| 181 |   void Clear(int nosi = INIT_NODES_SIZE) {destroy();setup(nosi);}; | 
|---|
| 182 |  | 
|---|
| 183 |   void DeleteEdges(); | 
|---|
| 184 |      | 
|---|
| 185 |   OldGraph<N,E> &operator=(OldGraph<N,E> &H); | 
|---|
| 186 | }; | 
|---|
| 187 |  | 
|---|
| 188 | ////////////////////////////////////////////////////////////////////// | 
|---|
| 189 | // Template Definitions | 
|---|
| 190 | ////////////////////////////////////////////////////////////////////// | 
|---|
| 191 |  | 
|---|
| 192 | //#include <stdio.h> | 
|---|
| 193 |  | 
|---|
| 194 | //********************************************************************** | 
|---|
| 195 | //                          OldGraph definitions | 
|---|
| 196 | //********************************************************************** | 
|---|
| 197 |  | 
|---|
| 198 | template<class N, class E> void OldGraph<N,E>::setup(int nosi) { | 
|---|
| 199 |   int i; | 
|---|
| 200 |  | 
|---|
| 201 |   //Set up nodes | 
|---|
| 202 |   nodenum = 0; | 
|---|
| 203 |   nodes_size = nosi; | 
|---|
| 204 |   // nodes = (nodes_t*) new char[sizeof(nodes_t)*nodes_size]; | 
|---|
| 205 |   nodes = (nodes_t*) new nodes_t [nodes_size]; | 
|---|
| 206 |   for(i=0;i<nodes_size;i++) | 
|---|
| 207 |     { | 
|---|
| 208 |       nodes[i].prev=i-1; | 
|---|
| 209 |       nodes[i].next=i+1; | 
|---|
| 210 |       nodes[i].indeg=FREE_NODE; | 
|---|
| 211 |       nodes[i].outdeg=0; | 
|---|
| 212 |       nodes[i].firstin=nodes[i].firstout=NULL; | 
|---|
| 213 |     } | 
|---|
| 214 |   firstnode=nodes[0].prev=nodes[nodes_size-1].next=INVALID; | 
|---|
| 215 |   freenodes=0; | 
|---|
| 216 |   //Set up edge-list_template_type; | 
|---|
| 217 |   freeedges = NULL; | 
|---|
| 218 |    | 
|---|
| 219 |   edges = new edge_block* [edge_block_max=INIT_EDGES_BLOCK_MAX]; | 
|---|
| 220 |   edge_block_num = 0; | 
|---|
| 221 |    | 
|---|
| 222 | } | 
|---|
| 223 |  | 
|---|
| 224 | template<class N, class E> void OldGraph<N,E>::destroy() | 
|---|
| 225 | { | 
|---|
| 226 |   int i; | 
|---|
| 227 |    | 
|---|
| 228 |   while(firstnode!=INVALID) Delete(firstnode); | 
|---|
| 229 |   delete [] nodes; | 
|---|
| 230 |   for(i=0;i<edge_block_num;i++) delete edges[i]; | 
|---|
| 231 |   delete [] edges; | 
|---|
| 232 | } | 
|---|
| 233 |  | 
|---|
| 234 | template<class N, class E> void OldGraph<N,E>::inc_nodes_size(int n) | 
|---|
| 235 | { | 
|---|
| 236 |   int i; | 
|---|
| 237 |   if(n<=nodenum) return; | 
|---|
| 238 |    | 
|---|
| 239 |   nodes_t *nn; | 
|---|
| 240 | //  nn = (nodes_t*) new char [sizeof(nodes_t)*n]; | 
|---|
| 241 |   nn = (nodes_t*) new nodes_t [n]; | 
|---|
| 242 |   for(i=0;i<nodes_size;i++) | 
|---|
| 243 |     { | 
|---|
| 244 |       nn[i].Copy(nodes[i]); | 
|---|
| 245 |       if(nodes[i].indeg!=FREE_NODE) ((N*)(nodes[i].data))->~N(); | 
|---|
| 246 |     } | 
|---|
| 247 |    | 
|---|
| 248 |   delete [] nodes; | 
|---|
| 249 |   nodes = nn; | 
|---|
| 250 |   for(i=nodes_size;i<n;i++) | 
|---|
| 251 |     { | 
|---|
| 252 |       nodes[i].prev=i-1; | 
|---|
| 253 |       nodes[i].next=i+1; | 
|---|
| 254 |       nodes[i].indeg=FREE_NODE; | 
|---|
| 255 |       nodes[i].outdeg=0; | 
|---|
| 256 |       nodes[i].firstin=nodes[i].firstout=NULL; | 
|---|
| 257 |     } | 
|---|
| 258 |   nodes[nodes_size].prev=INVALID; | 
|---|
| 259 |   nodes[n-1].next=freenodes; | 
|---|
| 260 |   if(freenodes!=INVALID) nodes[freenodes].prev=n-1; | 
|---|
| 261 |   freenodes=nodes_size; | 
|---|
| 262 |   nodes_size=n; | 
|---|
| 263 | } | 
|---|
| 264 |  | 
|---|
| 265 | template<class N, class E> OldGraph<N,E> &OldGraph<N,E>::operator=(OldGraph<N,E> &H) | 
|---|
| 266 | { | 
|---|
| 267 |   Clean(); | 
|---|
| 268 |  | 
|---|
| 269 |   int i; | 
|---|
| 270 |   EdgePoint e; | 
|---|
| 271 |    | 
|---|
| 272 |   for(i=H.FirstNode();i!=INVALID;i=H.NextNode(i)) | 
|---|
| 273 |     { | 
|---|
| 274 |       AddNode(i); | 
|---|
| 275 |       operator()(i)=H(i); | 
|---|
| 276 |     } | 
|---|
| 277 |   for(i=H.FirstNode();i!=INVALID;i=H.NextNode(i)) | 
|---|
| 278 |     for(e=H.FirstOut(i);e;e=H.NextOut(e)) | 
|---|
| 279 |       operator()(AddEdge(i,H.To(e),H.Index(e)))=H(e); | 
|---|
| 280 |  | 
|---|
| 281 |    return *this; | 
|---|
| 282 | } | 
|---|
| 283 |  | 
|---|
| 284 | template<class N, class E> int OldGraph<N,E>::EdgeNum() | 
|---|
| 285 | { | 
|---|
| 286 |   int n=firstnode, m=0; | 
|---|
| 287 |   EdgePoint e; | 
|---|
| 288 |   while(n != INVALID) | 
|---|
| 289 |   {     | 
|---|
| 290 |     e=FirstOut(n); | 
|---|
| 291 |     while (e != NULL) | 
|---|
| 292 |     { | 
|---|
| 293 |       m++; | 
|---|
| 294 |       e=NextOut(e); | 
|---|
| 295 |     } | 
|---|
| 296 |     n=nodes[n].next; | 
|---|
| 297 |   } | 
|---|
| 298 |   return m; | 
|---|
| 299 | } | 
|---|
| 300 |  | 
|---|
| 301 | template<class N, class E> int OldGraph<N,E>::AddNode() | 
|---|
| 302 | { | 
|---|
| 303 |   int i; | 
|---|
| 304 |    | 
|---|
| 305 |   if(freenodes==INVALID) inc_nodes_size(2*nodes_size); | 
|---|
| 306 |    | 
|---|
| 307 |   i=freenodes; | 
|---|
| 308 |   if(firstnode!=INVALID) nodes[firstnode].prev=i; | 
|---|
| 309 |   freenodes=nodes[i].next; | 
|---|
| 310 |   new(nodes[i].data) N;  //Explicit constructor call | 
|---|
| 311 |   nodes[i].next=firstnode; | 
|---|
| 312 |   nodes[i].prev=INVALID; | 
|---|
| 313 |   nodes[i].indeg=0; | 
|---|
| 314 |   firstnode=i; | 
|---|
| 315 |   if(freenodes!=INVALID) nodes[freenodes].prev=INVALID; | 
|---|
| 316 |   nodenum++; | 
|---|
| 317 |   return i; | 
|---|
| 318 | } | 
|---|
| 319 |  | 
|---|
| 320 | template<class N, class E> int OldGraph<N,E>::AddNode(int n) | 
|---|
| 321 | { | 
|---|
| 322 |   int i; | 
|---|
| 323 |    | 
|---|
| 324 |   if(n>=nodes_size) | 
|---|
| 325 |     { | 
|---|
| 326 |       for(i=INIT_NODES_SIZE;i<=n;i*=2) ; | 
|---|
| 327 |       inc_nodes_size(i); | 
|---|
| 328 |     } | 
|---|
| 329 |    | 
|---|
| 330 |   if(nodes[n].indeg==FREE_NODE) | 
|---|
| 331 |     { | 
|---|
| 332 |       new(nodes[n].data) N;  //Explicit constructor call | 
|---|
| 333 |       if(nodes[n].next!=INVALID) nodes[nodes[n].next].prev = nodes[n].prev; | 
|---|
| 334 |       if(nodes[n].prev!=INVALID) nodes[nodes[n].prev].next = nodes[n].next; | 
|---|
| 335 |       else freenodes = nodes[n].next; | 
|---|
| 336 |        | 
|---|
| 337 |       nodes[n].prev = INVALID; | 
|---|
| 338 |       if((nodes[n].next = firstnode)!=INVALID) nodes[firstnode].prev=n; | 
|---|
| 339 |       firstnode = n; | 
|---|
| 340 |       nodenum++; | 
|---|
| 341 |       nodes[n].indeg=0; | 
|---|
| 342 |     } | 
|---|
| 343 |   return n; | 
|---|
| 344 | } | 
|---|
| 345 |  | 
|---|
| 346 | template<class N, class E> void OldGraph<N,E>::Delete(int n) | 
|---|
| 347 | { | 
|---|
| 348 |   if(n==INVALID||nodes[n].indeg==FREE_NODE) return; | 
|---|
| 349 |  | 
|---|
| 350 |   EdgePoint e; | 
|---|
| 351 |    | 
|---|
| 352 |   while(e=FirstIn(n)) Delete(e); | 
|---|
| 353 |   while(e=FirstOut(n)) Delete(e); | 
|---|
| 354 |    | 
|---|
| 355 |   if(n==firstnode) firstnode=nodes[n].next; | 
|---|
| 356 |   if(nodes[n].prev!=INVALID) nodes[nodes[n].prev].next=nodes[n].next; | 
|---|
| 357 |   if(nodes[n].next!=INVALID) nodes[nodes[n].next].prev=nodes[n].prev; | 
|---|
| 358 |   if(freenodes!=INVALID) nodes[freenodes].prev=n; | 
|---|
| 359 |   nodes[n].next=freenodes; | 
|---|
| 360 |   nodes[n].prev=INVALID; | 
|---|
| 361 |   nodes[n].indeg=FREE_NODE; | 
|---|
| 362 |   ((N*)(nodes[n].data))->~N();  //Explicit destructor call | 
|---|
| 363 |   freenodes=n; | 
|---|
| 364 |  | 
|---|
| 365 |   nodenum--; | 
|---|
| 366 | } | 
|---|
| 367 |  | 
|---|
| 368 | template<class N, class E> EdgePoint OldGraph<N,E>::AddEdge(int f, int t) | 
|---|
| 369 | { | 
|---|
| 370 |   int i; | 
|---|
| 371 |   edge_block *peb; | 
|---|
| 372 |   edge_block **ppeb; | 
|---|
| 373 |   edge_t *e; | 
|---|
| 374 |    | 
|---|
| 375 |   if(!freeedges) | 
|---|
| 376 |     { | 
|---|
| 377 |       if(edge_block_num>=edge_block_max) | 
|---|
| 378 |         { | 
|---|
| 379 |           ppeb = new edge_block* [edge_block_max*=2]; | 
|---|
| 380 |           for(i=0;i<edge_block_num;i++) ppeb[i]=edges[i]; | 
|---|
| 381 |           delete [] edges; | 
|---|
| 382 |           edges = ppeb; | 
|---|
| 383 |         } | 
|---|
| 384 |       peb = new edge_block; | 
|---|
| 385 |       edges[edge_block_num] = peb; | 
|---|
| 386 |        | 
|---|
| 387 |       for(i=0;i<EDGE_BLOCK_SIZE;i++) | 
|---|
| 388 |         { | 
|---|
| 389 |           ((edge_t*)peb->fields)[i].nextin=((edge_t*)peb->fields)+(i+1); | 
|---|
| 390 |           ((edge_t*)peb->fields)[i].previn=((edge_t*)peb->fields)+(i-1); | 
|---|
| 391 |           ((edge_t*)peb->fields)[i].index.block = edge_block_num; | 
|---|
| 392 |           ((edge_t*)peb->fields)[i].index.index = i; | 
|---|
| 393 |           ((edge_t*)peb->fields)[i].from = INVALID; | 
|---|
| 394 |         } | 
|---|
| 395 |       ((edge_t*)peb->fields)[0].previn= | 
|---|
| 396 |         ((edge_t*)peb->fields)[EDGE_BLOCK_SIZE-1].nextin=NULL; | 
|---|
| 397 |       freeedges = (edge_t*)peb->fields; | 
|---|
| 398 |       edge_block_num++; | 
|---|
| 399 |     } | 
|---|
| 400 |    | 
|---|
| 401 |   e=(edge_t *)freeedges; | 
|---|
| 402 |   new (e->data) E;  //Explicit constructor call | 
|---|
| 403 |   freeedges=e->nextin; | 
|---|
| 404 |   if(freeedges) freeedges->previn=NULL; | 
|---|
| 405 |    | 
|---|
| 406 |   e->from=f; e->to=t; | 
|---|
| 407 |   e->previn=e->prevout=NULL; | 
|---|
| 408 |   e->nextin=nodes[t].firstin; | 
|---|
| 409 |   e->nextout=nodes[f].firstout; | 
|---|
| 410 |   if(nodes[t].firstin) nodes[t].firstin->previn=e; | 
|---|
| 411 |   if(nodes[f].firstout) nodes[f].firstout->prevout=e; | 
|---|
| 412 |   nodes[t].firstin=nodes[f].firstout=e; | 
|---|
| 413 |   nodes[t].indeg++; nodes[f].outdeg++; | 
|---|
| 414 |  | 
|---|
| 415 |   return (EdgePoint)e; | 
|---|
| 416 |    | 
|---|
| 417 | } | 
|---|
| 418 |  | 
|---|
| 419 | template<class N, class E> | 
|---|
| 420 | EdgePoint OldGraph<N,E>::AddEdge(int f, int t, EdgeIndex in) | 
|---|
| 421 | { | 
|---|
| 422 |   int i; | 
|---|
| 423 |   edge_block *peb; | 
|---|
| 424 |   edge_block **ppeb; | 
|---|
| 425 |   edge_t *e; | 
|---|
| 426 |    | 
|---|
| 427 |   while(edge_block_num<=in.block) | 
|---|
| 428 |     { | 
|---|
| 429 |       if(edge_block_num>=edge_block_max) | 
|---|
| 430 |         { | 
|---|
| 431 |           ppeb = new edge_block* [edge_block_max*=2]; | 
|---|
| 432 |           for(i=0;i<edge_block_num;i++) ppeb[i]=edges[i]; | 
|---|
| 433 |           delete [] edges; | 
|---|
| 434 |           edges = ppeb; | 
|---|
| 435 |         } | 
|---|
| 436 |       peb = new edge_block; | 
|---|
| 437 |       edges[edge_block_num] = peb; | 
|---|
| 438 |        | 
|---|
| 439 |       for(i=0;i<EDGE_BLOCK_SIZE;i++) | 
|---|
| 440 |         { | 
|---|
| 441 |           ((edge_t*)peb->fields)[i].nextin=((edge_t*)peb->fields)+(i+1); | 
|---|
| 442 |           ((edge_t*)peb->fields)[i].previn=((edge_t*)peb->fields)+(i-1); | 
|---|
| 443 |           ((edge_t*)peb->fields)[i].index.block = edge_block_num; | 
|---|
| 444 |           ((edge_t*)peb->fields)[i].index.index = i; | 
|---|
| 445 |           ((edge_t*)peb->fields)[i].from = INVALID; | 
|---|
| 446 |         } | 
|---|
| 447 |       ((edge_t*)peb->fields)[0].previn=NULL; | 
|---|
| 448 |       ((edge_t*)peb->fields)[EDGE_BLOCK_SIZE-1].nextin=freeedges; | 
|---|
| 449 |       if(freeedges) | 
|---|
| 450 |         freeedges->previn = ((edge_t*)peb->fields) + (EDGE_BLOCK_SIZE-1); | 
|---|
| 451 |       freeedges = (edge_t*)peb->fields; | 
|---|
| 452 |       edge_block_num++; | 
|---|
| 453 |     } | 
|---|
| 454 |    | 
|---|
| 455 |    | 
|---|
| 456 |   e=((edge_t*)(edges[in.block]->fields))+in.index; | 
|---|
| 457 |   if(e->from==INVALID) | 
|---|
| 458 |     { | 
|---|
| 459 |       if(e->previn) e->previn->nextin = e->nextin; | 
|---|
| 460 |                else freeedges = e->nextin; | 
|---|
| 461 |       if(e->nextin) e->nextin->previn = e->previn; | 
|---|
| 462 |  | 
|---|
| 463 |       new (e->data) E;  //Explicit constructor call | 
|---|
| 464 |        | 
|---|
| 465 |       e->from=f; e->to=t; | 
|---|
| 466 |       e->previn=e->prevout=NULL; | 
|---|
| 467 |       e->nextin=nodes[t].firstin; | 
|---|
| 468 |       e->nextout=nodes[f].firstout; | 
|---|
| 469 |       if(nodes[t].firstin) nodes[t].firstin->previn=e; | 
|---|
| 470 |       if(nodes[f].firstout) nodes[f].firstout->prevout=e; | 
|---|
| 471 |       nodes[t].firstin=nodes[f].firstout=e; | 
|---|
| 472 |       nodes[t].indeg++; nodes[f].outdeg++; | 
|---|
| 473 |     } | 
|---|
| 474 |   return (EdgePoint)e; | 
|---|
| 475 | } | 
|---|
| 476 |  | 
|---|
| 477 | template<class N, class E> void OldGraph<N,E>::Delete(EdgePoint e) | 
|---|
| 478 | { | 
|---|
| 479 |   if(!e||e->from==INVALID) return; | 
|---|
| 480 |    | 
|---|
| 481 |   ((E*)(((edge_t*)e)->data))->~E();  //Explicit destructor call | 
|---|
| 482 |    | 
|---|
| 483 |   nodes[e->from].outdeg--; nodes[e->to].indeg--; | 
|---|
| 484 |  | 
|---|
| 485 |    | 
|---|
| 486 |   if(e->previn) | 
|---|
| 487 |     e->previn->nextin=e->nextin; | 
|---|
| 488 |   else nodes[e->to].firstin=e->nextin; | 
|---|
| 489 |   if(e->prevout) | 
|---|
| 490 |     e->prevout->nextout=e->nextout; | 
|---|
| 491 |   else nodes[e->from].firstout=e->nextout; | 
|---|
| 492 |   if(e->nextin) | 
|---|
| 493 |     e->nextin->previn=e->previn; | 
|---|
| 494 |   if(e->nextout) | 
|---|
| 495 |     e->nextout->prevout=e->prevout; | 
|---|
| 496 |    | 
|---|
| 497 |   if(freeedges) freeedges->previn=e; | 
|---|
| 498 |   e->previn=NULL; e->nextin=freeedges; | 
|---|
| 499 |  | 
|---|
| 500 |   e->from = INVALID; | 
|---|
| 501 |   freeedges=e; | 
|---|
| 502 | } | 
|---|
| 503 |  | 
|---|
| 504 | template<class N, class E> EdgePoint OldGraph<N,E>::Edge(int f, int t) | 
|---|
| 505 | { | 
|---|
| 506 |   EdgePoint e; | 
|---|
| 507 |    | 
|---|
| 508 |   for(e=nodes[f].firstout;e&&e->to!=t;e=e->nextout) ; | 
|---|
| 509 |    | 
|---|
| 510 |   return (EdgePoint) e; | 
|---|
| 511 | } | 
|---|
| 512 |  | 
|---|
| 513 | template<class N, class E> void OldGraph<N,E>::Reverse(EdgePoint e) | 
|---|
| 514 | { | 
|---|
| 515 |   if(!e) return; | 
|---|
| 516 |  | 
|---|
| 517 |   nodes[e->from].outdeg--; nodes[e->to].indeg--; | 
|---|
| 518 |    | 
|---|
| 519 |   if(e->previn) | 
|---|
| 520 |     e->previn->nextin=e->nextin; | 
|---|
| 521 |   else nodes[e->to].firstin=e->nextin; | 
|---|
| 522 |   if(e->prevout) | 
|---|
| 523 |     e->prevout->nextout=e->nextout; | 
|---|
| 524 |   else nodes[e->from].firstout=e->nextout; | 
|---|
| 525 |   if(e->nextin) | 
|---|
| 526 |     e->nextin->previn=e->previn; | 
|---|
| 527 |   if(e->nextout) | 
|---|
| 528 |     e->nextout->prevout=e->prevout; | 
|---|
| 529 |    | 
|---|
| 530 |   int t,f; | 
|---|
| 531 |   f=e->to;e->to=t=e->from; | 
|---|
| 532 |   e->from=f; | 
|---|
| 533 |  | 
|---|
| 534 |   e->previn=e->prevout=NULL; | 
|---|
| 535 |   e->nextin=nodes[t].firstin; | 
|---|
| 536 |   e->nextout=nodes[f].firstout; | 
|---|
| 537 |   if(nodes[t].firstin) nodes[t].firstin->previn=e; | 
|---|
| 538 |   if(nodes[f].firstout) nodes[f].firstout->prevout=e; | 
|---|
| 539 |   nodes[t].firstin=nodes[f].firstout=e; | 
|---|
| 540 |   nodes[t].indeg++; nodes[f].outdeg++; | 
|---|
| 541 |  | 
|---|
| 542 | } | 
|---|
| 543 |  | 
|---|
| 544 | template<class N, class E> void OldGraph<N,E>::DeleteEdges() | 
|---|
| 545 | { | 
|---|
| 546 |   int n; | 
|---|
| 547 |   for(n=FirstNode();n!=INVALID;n=NextNode(n)) | 
|---|
| 548 |     while(FirstOut(n)) Delete(FirstOut(n)); | 
|---|
| 549 | } | 
|---|
| 550 |  | 
|---|
| 551 | #endif | 
|---|