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