| [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 | 
|---|