00001
00002
00003
00004
00005
00006
00007
00008
00054 #ifdef _MSC_VER
00055 #pragma once
00056 #endif
00057
00058 #ifndef OGDF_GRAPH_D_H
00059 #define OGDF_GRAPH_D_H
00060
00061
00062 #include <ogdf/basic/List.h>
00063
00064
00065 namespace ogdf {
00066
00067
00068
00069
00070
00071
00072 class Graph;
00073 class NodeElement;
00074 class EdgeElement;
00075 class AdjElement;
00076 class FaceElement;
00077 class GraphListBase;
00078 class ClusterElement;
00079
00080
00082
00087 class GraphElement {
00088 friend class Graph;
00089 friend class GraphListBase;
00090
00091 protected:
00092 GraphElement *m_next;
00093 GraphElement *m_prev;
00094
00095 OGDF_NEW_DELETE
00096 };
00097
00098
00100 class GraphListBase {
00101 protected:
00102 GraphElement *m_head;
00103 GraphElement *m_tail;
00104
00105 public:
00107 GraphListBase() { m_head = m_tail = 0; }
00108
00109 ~GraphListBase() { }
00110
00112 void pushBack(GraphElement *pX) {
00113 pX->m_next = 0;
00114 pX->m_prev = m_tail;
00115 if (m_head)
00116 m_tail = m_tail->m_next = pX;
00117 else
00118 m_tail = m_head = pX;
00119 }
00120
00122 void insertAfter(GraphElement *pX, GraphElement *pY) {
00123 pX->m_prev = pY;
00124 GraphElement *pYnext = pX->m_next = pY->m_next;
00125 pY->m_next = pX;
00126 if (pYnext) pYnext->m_prev = pX;
00127 else m_tail = pX;
00128 }
00129
00131 void insertBefore(GraphElement *pX, GraphElement *pY) {
00132 pX->m_next = pY;
00133 GraphElement *pYprev = pX->m_prev = pY->m_prev;
00134 pY->m_prev = pX;
00135 if (pYprev) pYprev->m_next = pX;
00136 else m_head = pX;
00137 }
00138
00140 void del(GraphElement *pX) {
00141 GraphElement *pxPrev = pX->m_prev, *pxNext = pX->m_next;
00142
00143 if (pxPrev)
00144 pxPrev->m_next = pxNext;
00145 else
00146 m_head = pxNext;
00147 if (pxNext)
00148 pxNext->m_prev = pxPrev;
00149 else
00150 m_tail = pxPrev;
00151 }
00152
00154 template<class LIST>
00155 void sort(const LIST &newOrder) {
00156 GraphElement *pPred = 0;
00157 typename LIST::const_iterator it = newOrder.begin();
00158 if (!it.valid()) return;
00159
00160 m_head = *it;
00161 for(; it.valid(); ++it) {
00162 GraphElement *p = *it;
00163 if ((p->m_prev = pPred)) pPred->m_next = p;
00164 pPred = p;
00165 }
00166
00167 (m_tail = pPred)->m_next = 0;
00168 }
00169
00171 void reverse() {
00172 GraphElement *pX = m_head;
00173 m_head = m_tail;
00174 m_tail = pX;
00175 while(pX) {
00176 GraphElement *pY = pX->m_next;
00177 pX->m_next = pX->m_prev;
00178 pX = pX->m_prev = pY;
00179 }
00180 }
00181
00183 void swap(GraphElement *pX, GraphElement *pY) {
00184 if (pX->m_next == pY) {
00185 pX->m_next = pY->m_next;
00186 pY->m_prev = pX->m_prev;
00187 pY->m_next = pX;
00188 pX->m_prev = pY;
00189
00190 } else if(pY->m_next == pX) {
00191 pY->m_next = pX->m_next;
00192 pX->m_prev = pY->m_prev;
00193 pX->m_next = pY;
00194 pY->m_prev = pX;
00195
00196 } else {
00197 ogdf::swap(pX->m_next,pY->m_next);
00198 ogdf::swap(pX->m_prev,pY->m_prev);
00199 }
00200
00201 if(pX->m_prev)
00202 pX->m_prev->m_next = pX;
00203 else
00204 m_head = pX;
00205 if(pX->m_next)
00206 pX->m_next->m_prev = pX;
00207 else
00208 m_tail = pX;
00209
00210 if(pY->m_prev)
00211 pY->m_prev->m_next = pY;
00212 else
00213 m_head = pY;
00214 if(pY->m_next)
00215 pY->m_next->m_prev = pY;
00216 else
00217 m_tail = pY;
00218
00219 OGDF_ASSERT(consistencyCheck());
00220 }
00221
00222
00224 bool consistencyCheck() {
00225 if (m_head == 0) {
00226 return (m_tail == 0);
00227
00228 } else if (m_tail == 0) {
00229 return false;
00230
00231 } else {
00232 if (m_head->m_prev != 0)
00233 return false;
00234 if (m_tail->m_next != 0)
00235 return false;
00236
00237 GraphElement *pX = m_head;
00238 for(; pX; pX = pX->m_next) {
00239 if (pX->m_prev) {
00240 if (pX->m_prev->m_next != pX)
00241 return false;
00242 } else if(pX != m_head)
00243 return false;
00244
00245 if (pX->m_next) {
00246 if (pX->m_next->m_prev != pX)
00247 return false;
00248 } else if (pX != m_tail)
00249 return false;
00250 }
00251 }
00252
00253 return true;
00254 }
00255
00256 OGDF_NEW_DELETE
00257 };
00258
00259
00261
00264 template<class T> class GraphList : protected GraphListBase {
00265 public:
00267 GraphList() { }
00268
00269 ~GraphList() {
00270 if (m_head) g_memory.deallocateList(m_head,m_tail,sizeof(T));
00271 }
00272
00274 T *begin () const { return (T *)m_head; }
00276 T *rbegin() const { return (T *)m_tail; }
00277
00279 bool empty() { return m_head; }
00280
00282 void pushBack(T *pX) {
00283 GraphListBase::pushBack(pX);
00284 }
00285
00287 void insertAfter(T *pX, T *pY) {
00288 GraphListBase::insertAfter(pX,pY);
00289 }
00290
00292 void insertBefore(T *pX, T *pY) {
00293 GraphListBase::insertBefore(pX,pY);
00294 }
00295
00297 void move(T *pX, GraphList<T> &L, T *pY, Direction dir) {
00298 GraphListBase::del(pX);
00299 if (dir == after)
00300 L.insertAfter(pX,pY);
00301 else
00302 L.insertBefore(pX,pY);
00303 }
00304
00306 void move(T *pX, GraphList<T> &L) {
00307 GraphListBase::del(pX);
00308 L.pushBack(pX);
00309 }
00310
00312 void moveAfter(T *pX, T *pY){
00313 GraphListBase::del(pX);
00314 insertAfter(pX,pY);
00315 }
00316
00318 void moveBefore(T *pX, T *pY){
00319 GraphListBase::del(pX);
00320 insertBefore(pX,pY);
00321 }
00322
00324 void del(T *pX) {
00325 GraphListBase::del(pX);
00326 delete pX;
00327 }
00328
00330 void delPure(T *pX) {
00331 GraphListBase::del(pX);
00332 }
00333
00335 void clear() {
00336 if (m_head) {
00337 g_memory.deallocateList(m_head,m_tail,sizeof(T));
00338 m_head = m_tail = 0;
00339 }
00340 }
00341
00343 template<class T_LIST>
00344 void sort(const T_LIST &newOrder) {
00345 GraphListBase::sort(newOrder);
00346 }
00347
00348
00350 void reverse() {
00351 GraphListBase::reverse();
00352 }
00353
00355 void swap(T *pX, T *pY) {
00356 GraphListBase::swap(pX,pY);
00357 }
00358
00359
00361 bool consistencyCheck() {
00362 return GraphListBase::consistencyCheck();
00363 }
00364
00365
00366 OGDF_NEW_DELETE
00367 };
00368
00369
00370 typedef NodeElement *node;
00371 typedef EdgeElement *edge;
00372 typedef AdjElement *adjEntry;
00373
00374
00375
00377
00381 class AdjElement : private GraphElement {
00382 friend class Graph;
00383 friend class GraphListBase;
00384 friend class GraphList<AdjElement>;
00385
00386 AdjElement *m_twin;
00387 edge m_edge;
00388 node m_node;
00389 int m_id;
00390
00392 AdjElement(node v) : m_node(v) { }
00394 AdjElement(edge e, int id) : m_edge(e), m_id(id) { }
00395
00396 public:
00398 edge theEdge() const { return m_edge; }
00400 operator edge() const { return m_edge; }
00402 node theNode() const { return m_node; }
00403
00405 adjEntry twin() const { return m_twin; }
00406
00408 node twinNode() const { return m_twin->m_node; }
00409
00411 int index() const { return m_id; }
00412
00413
00414
00415
00417 adjEntry clockwiseFaceSucc() const { return m_twin->cyclicPred(); }
00419 adjEntry clockwiseFacePred() const { return cyclicSucc()->m_twin; }
00421 adjEntry counterClockwiseFaceSucc() const { return m_twin->cyclicSucc(); }
00423 adjEntry counterClockwiseFacePred() const { return cyclicPred()->m_twin; }
00424
00425
00427 adjEntry faceCycleSucc() const { return clockwiseFaceSucc(); }
00429 adjEntry faceCyclePred() const { return clockwiseFacePred(); }
00430
00431
00433 adjEntry succ() const { return (adjEntry)m_next; }
00435 adjEntry pred() const { return (adjEntry)m_prev; }
00436
00438 adjEntry cyclicSucc() const;
00440 adjEntry cyclicPred() const;
00441
00442 #ifdef OGDF_DEBUG
00443 const Graph *graphOf() const;
00444 #endif
00445
00446 OGDF_NEW_DELETE
00447 };
00448
00449
00451 class NodeElement : private GraphElement {
00452 friend class Graph;
00453 friend class GraphList<NodeElement>;
00454
00455 GraphList<AdjElement> m_adjEdges;
00456 int m_indeg;
00457 int m_outdeg;
00458 int m_id;
00459
00460 #ifdef OGDF_DEBUG
00461
00462 const Graph *m_pGraph;
00463 #endif
00464
00465
00466
00467 #ifdef OGDF_DEBUG
00469
00474 NodeElement(const Graph *pGraph, int id) :
00475 m_indeg(0), m_outdeg(0), m_id(id), m_pGraph(pGraph) { }
00476 #else
00477 NodeElement(int id) : m_indeg(0), m_outdeg(0), m_id(id) { }
00478 #endif
00479
00480
00481 public:
00483 int index() const { return m_id; }
00484
00486 int indeg() const { return m_indeg; }
00488 int outdeg() const { return m_outdeg; }
00490 int degree() const { return m_indeg + m_outdeg; }
00491
00493 adjEntry firstAdj() const { return m_adjEdges.begin(); }
00495 adjEntry lastAdj () const { return m_adjEdges.rbegin(); }
00496
00498 node succ() const { return (node)m_next; }
00500 node pred() const { return (node)m_prev; }
00501
00502 #ifdef OGDF_DEBUG
00504 const Graph *graphOf() const { return m_pGraph; }
00505 #endif
00506
00507 OGDF_NEW_DELETE
00508 };
00509
00510
00511 inline adjEntry AdjElement::cyclicSucc() const
00512 {
00513 return (m_next) ? (adjEntry)m_next : m_node->firstAdj();
00514 }
00515
00516 inline adjEntry AdjElement::cyclicPred() const
00517 {
00518 return (m_prev) ? (adjEntry)m_prev : m_node->lastAdj();
00519 }
00520
00521 inline bool test_forall_adj_edges(adjEntry &adj, edge &e)
00522 {
00523 if (adj) { e = adj->theEdge(); return true; }
00524 else return false;
00525 }
00526
00527
00528
00530 class EdgeElement : private GraphElement {
00531 friend class Graph;
00532 friend class GraphList<EdgeElement>;
00533
00534 node m_src;
00535 node m_tgt;
00536 AdjElement *m_adjSrc;
00537 AdjElement *m_adjTgt;
00538 int m_id;
00539
00541
00548 EdgeElement(node src, node tgt, AdjElement *adjSrc, AdjElement *adjTgt, int id) :
00549 m_src(src), m_tgt(tgt), m_adjSrc(adjSrc), m_adjTgt(adjTgt), m_id(id) { }
00550
00552
00557 EdgeElement(node src, node tgt, int id) :
00558 m_src(src), m_tgt(tgt), m_id(id) { }
00559
00560 public:
00562 int index() const { return m_id; }
00564 node source() const { return m_src; }
00566 node target() const { return m_tgt; }
00567
00569 adjEntry adjSource() const { return m_adjSrc; }
00571 adjEntry adjTarget() const { return m_adjTgt; }
00572
00574 node opposite(node v) const { return (v == m_src) ? m_tgt : m_src; }
00575
00576 bool isSelfLoop() const { return m_src == m_tgt; }
00577
00579 edge succ() const { return (edge)m_next; }
00581 edge pred() const { return (edge)m_prev; }
00582
00583 #ifdef OGDF_DEBUG
00585 const Graph *graphOf() const { return m_src->graphOf(); }
00586 #endif
00587
00589 bool isIncident(node v) const { return v == m_src || v == m_tgt; }
00590
00592 node commonNode(edge e) const { return (m_src==e->m_src || m_src==e->m_tgt) ? m_src : ((m_tgt==e->m_src || m_tgt==e->m_tgt) ? m_tgt: 0); }
00593
00594 OGDF_NEW_DELETE
00595 };
00596
00597
00598 #ifdef OGDF_DEBUG
00599 inline const Graph *AdjElement::graphOf() const {
00600 return m_node->graphOf();
00601 }
00602 #endif
00603
00604
00605 template<>inline bool doDestruction<node>(const node *) { return false; }
00606 template<>inline bool doDestruction<edge>(const edge *) { return false; }
00607 template<>inline bool doDestruction<adjEntry>(const adjEntry *) { return false; }
00608
00609 class NodeArrayBase;
00610 class EdgeArrayBase;
00611 class AdjEntryArrayBase;
00612 template<class T>class NodeArray;
00613 template<class T>class EdgeArray;
00614 template<class T>class AdjEntryArray;
00615 class GraphObserver;
00616
00617
00618
00619
00620
00621
00623 #define forall_nodes(v,G) for((v)=(G).firstNode(); (v); (v)=(v)->succ())
00625 #define forall_rev_nodes(v,G) for((v)=(G).lastNode(); (v); (v)=(v)->pred())
00626
00628 #define forall_edges(e,G) for((e)=(G).firstEdge(); (e); (e)=(e)->succ())
00630 #define forall_rev_edges(e,G) for((e)=(G).lastEdge(); (e); (e)=(e)->pred())
00631
00633 #define forall_adj(adj,v) for((adj)=(v)->firstAdj(); (adj); (adj)=(adj)->succ())
00635 #define forall_rev_adj(adj,v) for((adj)=(v)->lastAdj(); (adj); (adj)=(adj)->pred())
00636
00638 #define forall_adj_edges(e,v)\
00639 ogdf::adjEntry OGDF_VAR(__LINE__);\
00640 for(OGDF_VAR(__LINE__)=(v)->firstAdj();\
00641 ogdf::test_forall_adj_edges(OGDF_VAR(__LINE__),(e));\
00642 OGDF_VAR(__LINE__)=OGDF_VAR(__LINE__)->succ())
00643
00644
00646
00697 class Graph
00698 {
00699 GraphList<NodeElement> m_nodes;
00700 GraphList<EdgeElement> m_edges;
00701 int m_nNodes;
00702 int m_nEdges;
00703
00704 int m_nodeIdCount;
00705 int m_edgeIdCount;
00706
00707 int m_nodeArrayTableSize;
00708 int m_edgeArrayTableSize;
00709
00710 mutable ListPure<NodeArrayBase*> m_regNodeArrays;
00711 mutable ListPure<EdgeArrayBase*> m_regEdgeArrays;
00712 mutable ListPure<AdjEntryArrayBase*> m_regAdjArrays;
00713 mutable ListPure<GraphObserver*> m_regStructures;
00714
00715 GraphList<EdgeElement> m_hiddenEdges;
00716
00717 public:
00718
00719
00720
00721
00723 enum EdgeType {
00724 association = 0,
00725 generalization = 1,
00726 dependency = 2
00727 };
00728
00730 enum NodeType {
00731 vertex,
00732 dummy,
00733 generalizationMerger,
00734 generalizationExpander,
00735 highDegreeExpander,
00736 lowDegreeExpander,
00737 associationClass
00738 };
00739
00740
00742 Graph();
00743
00745
00750 Graph(const Graph &G);
00751
00752
00753 virtual ~Graph();
00754
00755
00760
00762 bool empty() const { return m_nNodes == 0; }
00763
00765 int numberOfNodes() const { return m_nNodes; }
00766
00768 int numberOfEdges() const { return m_nEdges; }
00769
00771 int maxNodeIndex() const { return m_nodeIdCount-1; }
00773 int maxEdgeIndex() const { return m_edgeIdCount-1; }
00775 int maxAdjEntryIndex() const { return (m_edgeIdCount<<1)-1; }
00776
00778 int nodeArrayTableSize() const { return m_nodeArrayTableSize; }
00780 int edgeArrayTableSize() const { return m_edgeArrayTableSize; }
00782 int adjEntryArrayTableSize() const { return m_edgeArrayTableSize << 1; }
00783
00785 node firstNode() const { return m_nodes.begin (); }
00787 node lastNode () const { return m_nodes.rbegin(); }
00788
00790 edge firstEdge() const { return m_edges.begin (); }
00792 edge lastEdge () const { return m_edges.rbegin(); }
00793
00795 node chooseNode() const;
00797 edge chooseEdge() const;
00798
00800 template<class NODELIST>
00801 void allNodes(NODELIST &nodes) const {
00802 nodes.clear();
00803 for (node v = m_nodes.begin(); v; v = v->succ())
00804 nodes.pushBack(v);
00805 }
00806
00808 template<class EDGELIST>
00809 void allEdges(EDGELIST &edges) const {
00810 edges.clear();
00811 for (edge e = m_edges.begin(); e; e = e->succ())
00812 edges.pushBack(e);
00813 }
00814
00816 template<class EDGELIST>
00817 void adjEdges(node v, EDGELIST &edges) const {
00818 edges.clear();
00819 edge e;
00820 forall_adj_edges(e,v)
00821 edges.pushBack(e);
00822 }
00823
00825 template<class ADJLIST>
00826 void adjEntries(node v, ADJLIST &entries) const {
00827 entries.clear();
00828 adjEntry adj;
00829 forall_adj(adj,v)
00830 entries.pushBack(adj);
00831 }
00832
00834 template<class EDGELIST>
00835 void inEdges(node v, EDGELIST &edges) const {
00836 edges.clear();
00837 edge e;
00838 forall_adj_edges(e,v)
00839 if (e->target() == v) edges.pushBack(e);
00840 }
00841
00843 template<class EDGELIST>
00844 void outEdges(node v, EDGELIST &edges) const {
00845 edges.clear();
00846 edge e;
00847 forall_adj_edges(e,v)
00848 if (e->source() == v) edges.pushBack(e);
00849 }
00850
00851
00853
00857
00859 node newNode();
00860
00862
00869 node newNode(int index);
00870
00872 edge newEdge(node v, node w);
00873
00875
00882 edge newEdge(node v, node w, int index);
00883
00885
00897 edge newEdge(adjEntry adjSrc, adjEntry adjTgt, Direction dir = ogdf::after);
00898
00900
00908 edge newEdge(node v, adjEntry adjTgt);
00909
00911
00919 edge newEdge(adjEntry adjSrc, node w);
00920
00921
00923
00927
00929 void delNode(node v);
00930
00932 void delEdge(edge e);
00933
00935 void clear();
00936
00937
00939
00947
00949
00954 void hideEdge(edge e);
00955
00957
00960 void restoreEdge(edge e);
00961
00963 void restoreAllEdges();
00964
00969
00970
00972
00978 virtual edge split(edge e);
00979
00981
00988 void unsplit(node u);
00989
00991
00999 virtual void unsplit(edge eIn, edge eOut);
01000
01002
01019 node splitNode(adjEntry adjStartLeft, adjEntry adjStartRight);
01020
01022 node contract(edge e);
01023
01024
01025
01026
01027 void move(edge e, adjEntry adjSrc, Direction dirSrc,
01028 adjEntry adjTgt, Direction dirTgt);
01029
01031
01034 void moveTarget(edge e, node w);
01035
01037
01041 void moveTarget(edge e, adjEntry adjTgt, Direction dir);
01042
01044
01047 void moveSource(edge e, node w);
01048
01050
01054 void moveSource(edge e, adjEntry adjSrc, Direction dir);
01055
01057
01058 edge searchEdge (node v, node w) const;
01059
01061 void reverseEdge(edge e);
01062
01064 void reverseAllEdges();
01065
01067
01070 template<class NODELIST>
01071 void collaps(NODELIST &nodes){
01072 node v = nodes.popFrontRet();
01073 while (!nodes.empty())
01074 {
01075 node w = nodes.popFrontRet();
01076 adjEntry adj = w->firstAdj();
01077 while (adj !=0)
01078 {
01079 adjEntry succ = adj->succ();
01080 edge e = adj->theEdge();
01081 if (e->source() == v || e->target() == v)
01082 delEdge(e);
01083 else if (e->source() == w)
01084 moveSource(e,v);
01085 else
01086 moveTarget(e,v);
01087 adj = succ;
01088 }
01089 delNode(w);
01090 }
01091 }
01092
01094
01097 template<class ADJ_ENTRY_LIST>
01098 void sort(node v, const ADJ_ENTRY_LIST &newOrder) {
01099 #ifdef OGDF_DEBUG
01100 typename ADJ_ENTRY_LIST::const_iterator it;
01101 for(it = newOrder.begin(); it.valid() ; ++it) {
01102 OGDF_ASSERT((*it)->theNode() == v);
01103 }
01104 #endif
01105 v->m_adjEdges.sort(newOrder);
01106 }
01107
01109 void reverseAdjEdges(node v) {
01110 v->m_adjEdges.reverse();
01111 }
01112
01114
01120 void moveAdj(adjEntry adjMove, Direction dir, adjEntry adjPos) {
01121 OGDF_ASSERT(adjMove->graphOf() == this && adjPos->graphOf() == this);
01122 OGDF_ASSERT(adjMove != 0 && adjPos != 0);
01123 GraphList<AdjElement> &adjList = adjMove->m_node->m_adjEdges;
01124 adjList.move(adjMove, adjList, adjPos, dir);
01125 }
01126
01128
01133 void moveAdjAfter(adjEntry adjMove, adjEntry adjAfter) {
01134 OGDF_ASSERT(adjMove->graphOf() == this && adjAfter->graphOf() == this);
01135 OGDF_ASSERT(adjMove != 0 && adjAfter != 0);
01136 adjMove->m_node->m_adjEdges.moveAfter(adjMove,adjAfter);
01137 }
01138
01140
01145 void moveAdjBefore(adjEntry adjMove, adjEntry adjBefore) {
01146 OGDF_ASSERT(adjMove->graphOf() == this && adjBefore->graphOf() == this);
01147 OGDF_ASSERT(adjMove != 0 && adjBefore != 0);
01148 adjMove->m_node->m_adjEdges.moveBefore(adjMove,adjBefore);
01149 }
01150
01152 void reverseAdjEdges();
01153
01155
01158 void swapAdjEdges(adjEntry adj1, adjEntry adj2) {
01159 OGDF_ASSERT(adj1->theNode() == adj2->theNode());
01160 OGDF_ASSERT(adj1->graphOf() == this);
01161
01162 adj1->theNode()->m_adjEdges.swap(adj1,adj2);
01163 }
01164
01165
01167
01171
01173 bool readGML(const char *fileName);
01174
01176 bool readGML(istream &is);
01177
01179 void writeGML(const char *fileName) const;
01180
01182 void writeGML(ostream &os) const;
01183
01185 bool readLEDAGraph(const char *fileName);
01186
01188 bool readLEDAGraph(istream &is);
01189
01190
01192
01196
01198
01206 int genus() const;
01207
01209 bool representsCombEmbedding() const {
01210 return (genus() == 0);
01211 }
01212
01214
01217 bool consistencyCheck() const;
01218
01219
01221
01227
01229 ListIterator<NodeArrayBase*> registerArray(NodeArrayBase *pNodeArray) const;
01231 ListIterator<EdgeArrayBase*> registerArray(EdgeArrayBase *pEdgeArray) const;
01233 ListIterator<AdjEntryArrayBase*> registerArray(AdjEntryArrayBase *pAdjArray) const;
01235 ListIterator<GraphObserver*> registerStructure(GraphObserver *pStructure) const;
01236
01238 void unregisterArray(ListIterator<NodeArrayBase*> it) const;
01240 void unregisterArray(ListIterator<EdgeArrayBase*> it) const;
01242 void unregisterArray(ListIterator<AdjEntryArrayBase*> it) const;
01244 void unregisterStructure(ListIterator<GraphObserver*> it) const;
01245
01246
01248
01272 void resetEdgeIdCount(int maxId);
01273
01274
01276
01280
01281
01286 Graph &operator=(const Graph &G);
01287
01288 OGDF_NEW_DELETE
01289
01291
01292
01294 static int nextPower2(int start, int idCount);
01295
01296
01297 protected:
01298 void construct(const Graph &G, NodeArray<node> &mapNode,
01299 EdgeArray<edge> &mapEdge);
01300
01301 void assign(const Graph &G, NodeArray<node> &mapNode,
01302 EdgeArray<edge> &mapEdge);
01303
01310 void constructInitByNodes(
01311 const Graph &G,
01312 const List<node> &nodes,
01313 NodeArray<node> &mapNode,
01314 EdgeArray<edge> &mapEdge);
01315
01316 void constructInitByActiveNodes(
01317 const List<node> &nodes,
01318 const NodeArray<bool> &activeNodes,
01319 NodeArray<node> &mapNode,
01320 EdgeArray<edge> &mapEdge);
01321
01322 private:
01323 void copy(const Graph &G, NodeArray<node> &mapNode,
01324 EdgeArray<edge> &mapEdge);
01325 void copy(const Graph &G);
01326
01327 edge createEdgeElement(node v, node w, adjEntry adjSrc, adjEntry adjTgt);
01328 node pureNewNode();
01329
01330
01331 void moveAdj(adjEntry adj, node w);
01332
01333 void reinitArrays();
01334 void reinitStructures();
01335 void resetAdjEntryIndex(int newIndex, int oldIndex);
01336
01337 bool readToEndOfLine(istream &is);
01338 };
01339
01340
01341
01343 class BucketSourceIndex : public BucketFunc<edge> {
01344 public:
01346 int getBucket(const edge &e) { return e->source()->index(); }
01347 };
01348
01350 class BucketTargetIndex : public BucketFunc<edge> {
01351 public:
01353 int getBucket(const edge &e) { return e->target()->index(); }
01354 };
01355
01356
01357 }
01358
01359 #endif
01360