| [1] | 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(); | 
|---|
| [3] | 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);}; | 
|---|
| [1] | 120 |   int AddNode(); | 
|---|
| [3] | 121 |   void AddNodeBlock(int n) const {for(int i=0;i<n;i++) AddNode();} | 
|---|
| [1] | 122 |   int AddNode(int n); | 
|---|
 | 123 |   void Delete(int n); | 
|---|
| [3] | 124 |   int isaNode(int n) const  | 
|---|
 | 125 |         {return n>=0&&n<nodes_size&&nodes[n].indeg!=FREE_NODE;}; | 
|---|
| [1] | 126 |    | 
|---|
| [3] | 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;}; | 
|---|
| [1] | 131 |  | 
|---|
| [3] | 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  | 
|---|
| [1] | 137 |     {return e->nextin;}; | 
|---|
| [3] | 138 |   EdgePoint NextOut(EdgePoint e)const  | 
|---|
| [1] | 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));}; | 
|---|
| [3] | 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);}; | 
|---|
| [1] | 147 |   void Delete(int f, int t) {Delete(Edge(f,t));}; | 
|---|
 | 148 |   void Reverse(EdgePoint e); | 
|---|
 | 149 |  | 
|---|
 | 150 |   // Functions for EdgeIndex | 
|---|
 | 151 |    | 
|---|
| [3] | 152 |   EdgePoint Edge(EdgeIndex i) const  | 
|---|
| [1] | 153 |     { return (EdgePoint)(edges[i.block]->fields+i.index);}; | 
|---|
| [3] | 154 |   EdgeIndex Index(EdgePoint e) const { return e->index;}; | 
|---|
 | 155 |   EdgeIndex Index(int f, int t) const { EdgePoint e; return Edge(f,t)->index; } | 
|---|
| [1] | 156 |   void Delete(EdgeIndex i) { Delete(Edge(i));}; | 
|---|
| [3] | 157 |   E& operator()(EdgeIndex i) const  | 
|---|
| [1] | 158 |      {return *(E*)(edges[i.block]->fields[i.index].data);}; | 
|---|
| [3] | 159 |   E& Data(EdgeIndex i) const  | 
|---|
| [1] | 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 |  | 
|---|
| [3] | 167 |   EdgePoint FirstEdge(int n) const  | 
|---|
| [1] | 168 |     { return (EdgePoint)(FirstIn(n)?FirstIn(n):FirstOut(n));}; | 
|---|
| [3] | 169 |   EdgePoint NextEdge(int n,EdgePoint e) const  | 
|---|
| [1] | 170 |     { return From(e)==n?NextOut(e):(NextIn(e)?NextIn(e):FirstOut(n)); }; | 
|---|
| [3] | 171 |   int Opposite(EdgePoint e,int n) const  | 
|---|
| [1] | 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 | 
|---|