00001
00002
00003
00004
00005
00006
00007
00008
00056 #ifdef _MSC_VER
00057 #pragma once
00058 #endif
00059
00060 #ifndef OGDF_GRAPH_D_H
00061 #define OGDF_GRAPH_D_H
00062
00063
00064 #include <ogdf/basic/List.h>
00065
00066
00067 namespace ogdf {
00068
00069
00070
00071
00072
00073
00074 class OGDF_EXPORT Graph;
00075 class OGDF_EXPORT NodeElement;
00076 class OGDF_EXPORT EdgeElement;
00077 class OGDF_EXPORT AdjElement;
00078 class OGDF_EXPORT FaceElement;
00079 class OGDF_EXPORT GraphListBase;
00080 class OGDF_EXPORT ClusterElement;
00081
00082
00084
00089 class OGDF_EXPORT GraphElement {
00090 friend class Graph;
00091 friend class GraphListBase;
00092
00093 protected:
00094 GraphElement *m_next;
00095 GraphElement *m_prev;
00096
00097 OGDF_NEW_DELETE
00098 };
00099
00100
00102 class OGDF_EXPORT GraphListBase {
00103 protected:
00104 GraphElement *m_head;
00105 GraphElement *m_tail;
00106
00107 public:
00109 GraphListBase() { m_head = m_tail = 0; }
00110
00111 ~GraphListBase() { }
00112
00114 void pushBack(GraphElement *pX) {
00115 pX->m_next = 0;
00116 pX->m_prev = m_tail;
00117 if (m_head)
00118 m_tail = m_tail->m_next = pX;
00119 else
00120 m_tail = m_head = pX;
00121 }
00122
00124 void insertAfter(GraphElement *pX, GraphElement *pY) {
00125 pX->m_prev = pY;
00126 GraphElement *pYnext = pX->m_next = pY->m_next;
00127 pY->m_next = pX;
00128 if (pYnext) pYnext->m_prev = pX;
00129 else m_tail = pX;
00130 }
00131
00133 void insertBefore(GraphElement *pX, GraphElement *pY) {
00134 pX->m_next = pY;
00135 GraphElement *pYprev = pX->m_prev = pY->m_prev;
00136 pY->m_prev = pX;
00137 if (pYprev) pYprev->m_next = pX;
00138 else m_head = pX;
00139 }
00140
00142 void del(GraphElement *pX) {
00143 GraphElement *pxPrev = pX->m_prev, *pxNext = pX->m_next;
00144
00145 if (pxPrev)
00146 pxPrev->m_next = pxNext;
00147 else
00148 m_head = pxNext;
00149 if (pxNext)
00150 pxNext->m_prev = pxPrev;
00151 else
00152 m_tail = pxPrev;
00153 }
00154
00156 template<class LIST>
00157 void sort(const LIST &newOrder) {
00158 GraphElement *pPred = 0;
00159 typename LIST::const_iterator it = newOrder.begin();
00160 if (!it.valid()) return;
00161
00162 m_head = *it;
00163 for(; it.valid(); ++it) {
00164 GraphElement *p = *it;
00165 if ((p->m_prev = pPred) != 0) pPred->m_next = p;
00166 pPred = p;
00167 }
00168
00169 (m_tail = pPred)->m_next = 0;
00170 }
00171
00173 void reverse() {
00174 GraphElement *pX = m_head;
00175 m_head = m_tail;
00176 m_tail = pX;
00177 while(pX) {
00178 GraphElement *pY = pX->m_next;
00179 pX->m_next = pX->m_prev;
00180 pX = pX->m_prev = pY;
00181 }
00182 }
00183
00185 void swap(GraphElement *pX, GraphElement *pY) {
00186 if (pX->m_next == pY) {
00187 pX->m_next = pY->m_next;
00188 pY->m_prev = pX->m_prev;
00189 pY->m_next = pX;
00190 pX->m_prev = pY;
00191
00192 } else if(pY->m_next == pX) {
00193 pY->m_next = pX->m_next;
00194 pX->m_prev = pY->m_prev;
00195 pX->m_next = pY;
00196 pY->m_prev = pX;
00197
00198 } else {
00199 swap(pX->m_next,pY->m_next);
00200 swap(pX->m_prev,pY->m_prev);
00201 }
00202
00203 if(pX->m_prev)
00204 pX->m_prev->m_next = pX;
00205 else
00206 m_head = pX;
00207 if(pX->m_next)
00208 pX->m_next->m_prev = pX;
00209 else
00210 m_tail = pX;
00211
00212 if(pY->m_prev)
00213 pY->m_prev->m_next = pY;
00214 else
00215 m_head = pY;
00216 if(pY->m_next)
00217 pY->m_next->m_prev = pY;
00218 else
00219 m_tail = pY;
00220
00221 OGDF_ASSERT(consistencyCheck());
00222 }
00223
00224
00226 bool consistencyCheck() {
00227 if (m_head == 0) {
00228 return (m_tail == 0);
00229
00230 } else if (m_tail == 0) {
00231 return false;
00232
00233 } else {
00234 if (m_head->m_prev != 0)
00235 return false;
00236 if (m_tail->m_next != 0)
00237 return false;
00238
00239 GraphElement *pX = m_head;
00240 for(; pX; pX = pX->m_next) {
00241 if (pX->m_prev) {
00242 if (pX->m_prev->m_next != pX)
00243 return false;
00244 } else if(pX != m_head)
00245 return false;
00246
00247 if (pX->m_next) {
00248 if (pX->m_next->m_prev != pX)
00249 return false;
00250 } else if (pX != m_tail)
00251 return false;
00252 }
00253 }
00254
00255 return true;
00256 }
00257
00258 OGDF_NEW_DELETE
00259 };
00260
00261
00263
00266 template<class T> class GraphList : protected GraphListBase {
00267 public:
00269 GraphList() { }
00270
00271 ~GraphList() {
00272 if (m_head)
00273 OGDF_ALLOCATOR::deallocateList(sizeof(T), m_head,m_tail);
00274 }
00275
00277 T *begin () const { return (T *)m_head; }
00279 T *rbegin() const { return (T *)m_tail; }
00280
00282 bool empty() { return m_head; }
00283
00285 void pushBack(T *pX) {
00286 GraphListBase::pushBack(pX);
00287 }
00288
00290 void insertAfter(T *pX, T *pY) {
00291 GraphListBase::insertAfter(pX,pY);
00292 }
00293
00295 void insertBefore(T *pX, T *pY) {
00296 GraphListBase::insertBefore(pX,pY);
00297 }
00298
00300 void move(T *pX, GraphList<T> &L, T *pY, Direction dir) {
00301 GraphListBase::del(pX);
00302 if (dir == after)
00303 L.insertAfter(pX,pY);
00304 else
00305 L.insertBefore(pX,pY);
00306 }
00307
00309 void move(T *pX, GraphList<T> &L) {
00310 GraphListBase::del(pX);
00311 L.pushBack(pX);
00312 }
00313
00315 void moveAfter(T *pX, T *pY){
00316 GraphListBase::del(pX);
00317 insertAfter(pX,pY);
00318 }
00319
00321 void moveBefore(T *pX, T *pY){
00322 GraphListBase::del(pX);
00323 insertBefore(pX,pY);
00324 }
00325
00327 void del(T *pX) {
00328 GraphListBase::del(pX);
00329 delete pX;
00330 }
00331
00333 void delPure(T *pX) {
00334 GraphListBase::del(pX);
00335 }
00336
00338 void clear() {
00339 if (m_head) {
00340 OGDF_ALLOCATOR::deallocateList(sizeof(T),m_head,m_tail);
00341 m_head = m_tail = 0;
00342 }
00343 }
00344
00346 template<class T_LIST>
00347 void sort(const T_LIST &newOrder) {
00348 GraphListBase::sort(newOrder);
00349 }
00350
00351
00353 void reverse() {
00354 GraphListBase::reverse();
00355 }
00356
00358 void swap(T *pX, T *pY) {
00359 GraphListBase::swap(pX,pY);
00360 }
00361
00362
00364 bool consistencyCheck() {
00365 return GraphListBase::consistencyCheck();
00366 }
00367
00368
00369 OGDF_NEW_DELETE
00370 };
00371
00372
00373 typedef NodeElement *node;
00374 typedef EdgeElement *edge;
00375 typedef AdjElement *adjEntry;
00376
00377
00378
00380
00384 class OGDF_EXPORT AdjElement : private GraphElement {
00385 friend class Graph;
00386 friend class GraphListBase;
00387 friend class GraphList<AdjElement>;
00388
00389 AdjElement *m_twin;
00390 edge m_edge;
00391 node m_node;
00392 int m_id;
00393
00395 AdjElement(node v) : m_node(v) { }
00397 AdjElement(edge e, int id) : m_edge(e), m_id(id) { }
00398
00399 public:
00401 edge theEdge() const { return m_edge; }
00403 operator edge() const { return m_edge; }
00405 node theNode() const { return m_node; }
00406
00408 adjEntry twin() const { return m_twin; }
00409
00411 node twinNode() const { return m_twin->m_node; }
00412
00414 int index() const { return m_id; }
00415
00416
00417
00418
00420 adjEntry clockwiseFaceSucc() const { return m_twin->cyclicPred(); }
00422 adjEntry clockwiseFacePred() const { return cyclicSucc()->m_twin; }
00424 adjEntry counterClockwiseFaceSucc() const { return m_twin->cyclicSucc(); }
00426 adjEntry counterClockwiseFacePred() const { return cyclicPred()->m_twin; }
00427
00428
00430 adjEntry faceCycleSucc() const { return clockwiseFaceSucc(); }
00432 adjEntry faceCyclePred() const { return clockwiseFacePred(); }
00433
00434
00436 adjEntry succ() const { return (adjEntry)m_next; }
00438 adjEntry pred() const { return (adjEntry)m_prev; }
00439
00441 adjEntry cyclicSucc() const;
00443 adjEntry cyclicPred() const;
00444
00445 #ifdef OGDF_DEBUG
00446 const Graph *graphOf() const;
00447 #endif
00448
00449 OGDF_NEW_DELETE
00450 };
00451
00452
00454 class OGDF_EXPORT NodeElement : private GraphElement {
00455 friend class Graph;
00456 friend class GraphList<NodeElement>;
00457
00458 GraphList<AdjElement> m_adjEdges;
00459 int m_indeg;
00460 int m_outdeg;
00461 int m_id;
00462
00463 #ifdef OGDF_DEBUG
00464
00465 const Graph *m_pGraph;
00466 #endif
00467
00468
00469
00470 #ifdef OGDF_DEBUG
00471
00472
00477 NodeElement(const Graph *pGraph, int id) :
00478 m_indeg(0), m_outdeg(0), m_id(id), m_pGraph(pGraph) { }
00479 #else
00480 NodeElement(int id) : m_indeg(0), m_outdeg(0), m_id(id) { }
00481 #endif
00482
00483
00484 public:
00486 int index() const { return m_id; }
00487
00489 int indeg() const { return m_indeg; }
00491 int outdeg() const { return m_outdeg; }
00493 int degree() const { return m_indeg + m_outdeg; }
00494
00496 adjEntry firstAdj() const { return m_adjEdges.begin(); }
00498 adjEntry lastAdj () const { return m_adjEdges.rbegin(); }
00499
00501 node succ() const { return (node)m_next; }
00503 node pred() const { return (node)m_prev; }
00504
00505 #ifdef OGDF_DEBUG
00506
00507 const Graph *graphOf() const { return m_pGraph; }
00508 #endif
00509
00510 OGDF_NEW_DELETE
00511 };
00512
00513
00514 inline adjEntry AdjElement::cyclicSucc() const
00515 {
00516 return (m_next) ? (adjEntry)m_next : m_node->firstAdj();
00517 }
00518
00519 inline adjEntry AdjElement::cyclicPred() const
00520 {
00521 return (m_prev) ? (adjEntry)m_prev : m_node->lastAdj();
00522 }
00523
00524 inline bool test_forall_adj_edges(adjEntry &adj, edge &e)
00525 {
00526 if (adj) { e = adj->theEdge(); return true; }
00527 else return false;
00528 }
00529
00530
00531
00533 class OGDF_EXPORT EdgeElement : private GraphElement {
00534 friend class Graph;
00535 friend class GraphList<EdgeElement>;
00536
00537 node m_src;
00538 node m_tgt;
00539 AdjElement *m_adjSrc;
00540 AdjElement *m_adjTgt;
00541 int m_id;
00542
00544
00551 EdgeElement(node src, node tgt, AdjElement *adjSrc, AdjElement *adjTgt, int id) :
00552 m_src(src), m_tgt(tgt), m_adjSrc(adjSrc), m_adjTgt(adjTgt), m_id(id) { }
00553
00555
00560 EdgeElement(node src, node tgt, int id) :
00561 m_src(src), m_tgt(tgt), m_id(id) { }
00562
00563 public:
00565 int index() const { return m_id; }
00567 node source() const { return m_src; }
00569 node target() const { return m_tgt; }
00570
00572 adjEntry adjSource() const { return m_adjSrc; }
00574 adjEntry adjTarget() const { return m_adjTgt; }
00575
00577 node opposite(node v) const { return (v == m_src) ? m_tgt : m_src; }
00578
00579 bool isSelfLoop() const { return m_src == m_tgt; }
00580
00582 edge succ() const { return (edge)m_next; }
00584 edge pred() const { return (edge)m_prev; }
00585
00586 #ifdef OGDF_DEBUG
00587
00588 const Graph *graphOf() const { return m_src->graphOf(); }
00589 #endif
00590
00592 bool isIncident(node v) const { return v == m_src || v == m_tgt; }
00593
00595 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); }
00596
00597 OGDF_NEW_DELETE
00598 };
00599
00600
00601 #ifdef OGDF_DEBUG
00602 inline const Graph *AdjElement::graphOf() const {
00603 return m_node->graphOf();
00604 }
00605 #endif
00606
00607
00608 template<>inline bool doDestruction<node>(const node *) { return false; }
00609 template<>inline bool doDestruction<edge>(const edge *) { return false; }
00610 template<>inline bool doDestruction<adjEntry>(const adjEntry *) { return false; }
00611
00612 class NodeArrayBase;
00613 class EdgeArrayBase;
00614 class AdjEntryArrayBase;
00615 template<class T> class NodeArray;
00616 template<class T> class EdgeArray;
00617 template<class T> class AdjEntryArray;
00618 class OGDF_EXPORT GraphObserver;
00619
00620
00621
00622
00623
00624
00626 #define forall_nodes(v,G) for((v)=(G).firstNode(); (v); (v)=(v)->succ())
00627
00628 #define forall_rev_nodes(v,G) for((v)=(G).lastNode(); (v); (v)=(v)->pred())
00629
00631 #define forall_edges(e,G) for((e)=(G).firstEdge(); (e); (e)=(e)->succ())
00632
00633 #define forall_rev_edges(e,G) for((e)=(G).lastEdge(); (e); (e)=(e)->pred())
00634
00636 #define forall_adj(adj,v) for((adj)=(v)->firstAdj(); (adj); (adj)=(adj)->succ())
00637
00638 #define forall_rev_adj(adj,v) for((adj)=(v)->lastAdj(); (adj); (adj)=(adj)->pred())
00639
00641 #define forall_adj_edges(e,v)\
00642 for(ogdf::adjEntry ogdf_loop_var=(v)->firstAdj();\
00643 ogdf::test_forall_adj_edges(ogdf_loop_var,(e));\
00644 ogdf_loop_var=ogdf_loop_var->succ())
00645
00646
00648
00699 class OGDF_EXPORT Graph
00700 {
00701 GraphList<NodeElement> m_nodes;
00702 GraphList<EdgeElement> m_edges;
00703 int m_nNodes;
00704 int m_nEdges;
00705
00706 int m_nodeIdCount;
00707 int m_edgeIdCount;
00708
00709 int m_nodeArrayTableSize;
00710 int m_edgeArrayTableSize;
00711
00712 mutable ListPure<NodeArrayBase*> m_regNodeArrays;
00713 mutable ListPure<EdgeArrayBase*> m_regEdgeArrays;
00714 mutable ListPure<AdjEntryArrayBase*> m_regAdjArrays;
00715 mutable ListPure<GraphObserver*> m_regStructures;
00716
00717 GraphList<EdgeElement> m_hiddenEdges;
00718
00719 public:
00720
00721
00722
00723
00725 enum EdgeType {
00726 association = 0,
00727 generalization = 1,
00728 dependency = 2
00729 };
00730
00732 enum NodeType {
00733 vertex,
00734 dummy,
00735 generalizationMerger,
00736 generalizationExpander,
00737 highDegreeExpander,
00738 lowDegreeExpander,
00739 associationClass
00740 };
00741
00742
00744 Graph();
00745
00747
00752 Graph(const Graph &G);
00753
00754
00755 virtual ~Graph();
00756
00757
00762
00764 bool empty() const { return m_nNodes == 0; }
00765
00767 int numberOfNodes() const { return m_nNodes; }
00768
00770 int numberOfEdges() const { return m_nEdges; }
00771
00773 int maxNodeIndex() const { return m_nodeIdCount-1; }
00775 int maxEdgeIndex() const { return m_edgeIdCount-1; }
00777 int maxAdjEntryIndex() const { return (m_edgeIdCount<<1)-1; }
00778
00780 int nodeArrayTableSize() const { return m_nodeArrayTableSize; }
00782 int edgeArrayTableSize() const { return m_edgeArrayTableSize; }
00784 int adjEntryArrayTableSize() const { return m_edgeArrayTableSize << 1; }
00785
00787 node firstNode() const { return m_nodes.begin (); }
00789 node lastNode () const { return m_nodes.rbegin(); }
00790
00792 edge firstEdge() const { return m_edges.begin (); }
00794 edge lastEdge () const { return m_edges.rbegin(); }
00795
00797 node chooseNode() const;
00799 edge chooseEdge() const;
00800
00802 template<class NODELIST>
00803 void allNodes(NODELIST &nodes) const {
00804 nodes.clear();
00805 for (node v = m_nodes.begin(); v; v = v->succ())
00806 nodes.pushBack(v);
00807 }
00808
00810 template<class EDGELIST>
00811 void allEdges(EDGELIST &edges) const {
00812 edges.clear();
00813 for (edge e = m_edges.begin(); e; e = e->succ())
00814 edges.pushBack(e);
00815 }
00816
00818 template<class EDGELIST>
00819 void adjEdges(node v, EDGELIST &edges) const {
00820 edges.clear();
00821 edge e;
00822 forall_adj_edges(e,v)
00823 edges.pushBack(e);
00824 }
00825
00827 template<class ADJLIST>
00828 void adjEntries(node v, ADJLIST &entries) const {
00829 entries.clear();
00830 adjEntry adj;
00831 forall_adj(adj,v)
00832 entries.pushBack(adj);
00833 }
00834
00836 template<class EDGELIST>
00837 void inEdges(node v, EDGELIST &edges) const {
00838 edges.clear();
00839 edge e;
00840 forall_adj_edges(e,v)
00841 if (e->target() == v) edges.pushBack(e);
00842 }
00843
00845 template<class EDGELIST>
00846 void outEdges(node v, EDGELIST &edges) const {
00847 edges.clear();
00848 edge e;
00849 forall_adj_edges(e,v)
00850 if (e->source() == v) edges.pushBack(e);
00851 }
00852
00853
00855
00859
00861 node newNode();
00862
00864
00871 node newNode(int index);
00872
00874 edge newEdge(node v, node w);
00875
00877
00884 edge newEdge(node v, node w, int index);
00885
00887
00899 edge newEdge(adjEntry adjSrc, adjEntry adjTgt, Direction dir = ogdf::after);
00900
00902
00910 edge newEdge(node v, adjEntry adjTgt);
00911
00913
00921 edge newEdge(adjEntry adjSrc, node w);
00922
00923
00925
00929
00931 void delNode(node v);
00932
00934 void delEdge(edge e);
00935
00937 void clear();
00938
00939
00941
00949
00951
00956 void hideEdge(edge e);
00957
00959
00962 void restoreEdge(edge e);
00963
00965 void restoreAllEdges();
00966
00971
00972
00974
00980 virtual edge split(edge e);
00981
00983
00990 void unsplit(node u);
00991
00993
01001 virtual void unsplit(edge eIn, edge eOut);
01002
01004
01021 node splitNode(adjEntry adjStartLeft, adjEntry adjStartRight);
01022
01024 node contract(edge e);
01025
01026
01027
01028
01029 void move(edge e, adjEntry adjSrc, Direction dirSrc,
01030 adjEntry adjTgt, Direction dirTgt);
01031
01033
01036 void moveTarget(edge e, node w);
01037
01039
01043 void moveTarget(edge e, adjEntry adjTgt, Direction dir);
01044
01046
01049 void moveSource(edge e, node w);
01050
01052
01056 void moveSource(edge e, adjEntry adjSrc, Direction dir);
01057
01059
01060 edge searchEdge (node v, node w) const;
01061
01063 void reverseEdge(edge e);
01064
01066 void reverseAllEdges();
01067
01069
01072 template<class NODELIST>
01073 void collaps(NODELIST &nodes){
01074 node v = nodes.popFrontRet();
01075 while (!nodes.empty())
01076 {
01077 node w = nodes.popFrontRet();
01078 adjEntry adj = w->firstAdj();
01079 while (adj !=0)
01080 {
01081 adjEntry succ = adj->succ();
01082 edge e = adj->theEdge();
01083 if (e->source() == v || e->target() == v)
01084 delEdge(e);
01085 else if (e->source() == w)
01086 moveSource(e,v);
01087 else
01088 moveTarget(e,v);
01089 adj = succ;
01090 }
01091 delNode(w);
01092 }
01093 }
01094
01096
01099 template<class ADJ_ENTRY_LIST>
01100 void sort(node v, const ADJ_ENTRY_LIST &newOrder) {
01101 #ifdef OGDF_DEBUG
01102 typename ADJ_ENTRY_LIST::const_iterator it;
01103 for(it = newOrder.begin(); it.valid() ; ++it) {
01104 OGDF_ASSERT((*it)->theNode() == v);
01105 }
01106 #endif
01107 v->m_adjEdges.sort(newOrder);
01108 }
01109
01111 void reverseAdjEdges(node v) {
01112 v->m_adjEdges.reverse();
01113 }
01114
01116
01122 void moveAdj(adjEntry adjMove, Direction dir, adjEntry adjPos) {
01123 OGDF_ASSERT(adjMove->graphOf() == this && adjPos->graphOf() == this);
01124 OGDF_ASSERT(adjMove != 0 && adjPos != 0);
01125 GraphList<AdjElement> &adjList = adjMove->m_node->m_adjEdges;
01126 adjList.move(adjMove, adjList, adjPos, dir);
01127 }
01128
01130
01135 void moveAdjAfter(adjEntry adjMove, adjEntry adjAfter) {
01136 OGDF_ASSERT(adjMove->graphOf() == this && adjAfter->graphOf() == this);
01137 OGDF_ASSERT(adjMove != 0 && adjAfter != 0);
01138 adjMove->m_node->m_adjEdges.moveAfter(adjMove,adjAfter);
01139 }
01140
01142
01147 void moveAdjBefore(adjEntry adjMove, adjEntry adjBefore) {
01148 OGDF_ASSERT(adjMove->graphOf() == this && adjBefore->graphOf() == this);
01149 OGDF_ASSERT(adjMove != 0 && adjBefore != 0);
01150 adjMove->m_node->m_adjEdges.moveBefore(adjMove,adjBefore);
01151 }
01152
01154 void reverseAdjEdges();
01155
01157
01160 void swapAdjEdges(adjEntry adj1, adjEntry adj2) {
01161 OGDF_ASSERT(adj1->theNode() == adj2->theNode());
01162 OGDF_ASSERT(adj1->graphOf() == this);
01163
01164 adj1->theNode()->m_adjEdges.swap(adj1,adj2);
01165 }
01166
01167
01169
01173
01175 bool readGML(const char *fileName);
01176
01178 bool readGML(istream &is);
01179
01181 void writeGML(const char *fileName) const;
01182
01184 void writeGML(ostream &os) const;
01185
01187 bool readLEDAGraph(const char *fileName);
01188
01190 bool readLEDAGraph(istream &is);
01191
01192
01194
01198
01200
01208 int genus() const;
01209
01211 bool representsCombEmbedding() const {
01212 return (genus() == 0);
01213 }
01214
01216
01219 bool consistencyCheck() const;
01220
01221
01223
01229
01231 ListIterator<NodeArrayBase*> registerArray(NodeArrayBase *pNodeArray) const;
01233 ListIterator<EdgeArrayBase*> registerArray(EdgeArrayBase *pEdgeArray) const;
01235 ListIterator<AdjEntryArrayBase*> registerArray(AdjEntryArrayBase *pAdjArray) const;
01237 ListIterator<GraphObserver*> registerStructure(GraphObserver *pStructure) const;
01238
01240 void unregisterArray(ListIterator<NodeArrayBase*> it) const;
01242 void unregisterArray(ListIterator<EdgeArrayBase*> it) const;
01244 void unregisterArray(ListIterator<AdjEntryArrayBase*> it) const;
01246 void unregisterStructure(ListIterator<GraphObserver*> it) const;
01247
01248
01250
01274 void resetEdgeIdCount(int maxId);
01275
01276
01278
01282
01283
01288 Graph &operator=(const Graph &G);
01289
01290 OGDF_MALLOC_NEW_DELETE
01291
01293
01294 public:
01295
01297 static int nextPower2(int start, int idCount);
01298
01299
01300 protected:
01301 void construct(const Graph &G, NodeArray<node> &mapNode,
01302 EdgeArray<edge> &mapEdge);
01303
01304 void assign(const Graph &G, NodeArray<node> &mapNode,
01305 EdgeArray<edge> &mapEdge);
01306
01313 void constructInitByNodes(
01314 const Graph &G,
01315 const List<node> &nodes,
01316 NodeArray<node> &mapNode,
01317 EdgeArray<edge> &mapEdge);
01318
01319 void constructInitByActiveNodes(
01320 const List<node> &nodes,
01321 const NodeArray<bool> &activeNodes,
01322 NodeArray<node> &mapNode,
01323 EdgeArray<edge> &mapEdge);
01324
01325 private:
01326 void copy(const Graph &G, NodeArray<node> &mapNode,
01327 EdgeArray<edge> &mapEdge);
01328 void copy(const Graph &G);
01329
01330 edge createEdgeElement(node v, node w, adjEntry adjSrc, adjEntry adjTgt);
01331 node pureNewNode();
01332
01333
01334 void moveAdj(adjEntry adj, node w);
01335
01336 void reinitArrays();
01337 void reinitStructures();
01338 void resetAdjEntryIndex(int newIndex, int oldIndex);
01339
01340 bool readToEndOfLine(istream &is);
01341 };
01342
01343
01344
01346 class OGDF_EXPORT BucketSourceIndex : public BucketFunc<edge> {
01347 public:
01349 int getBucket(const edge &e) { return e->source()->index(); }
01350 };
01351
01353 class OGDF_EXPORT BucketTargetIndex : public BucketFunc<edge> {
01354 public:
01356 int getBucket(const edge &e) { return e->target()->index(); }
01357 };
01358
01359
01360 }
01361
01362 #endif
01363