00001
00002
00003
00004
00005
00006
00007
00008
00046 #ifdef _MSC_VER
00047 #pragma once
00048 #endif
00049
00050 #ifndef OGDF_GRAPH_D_H
00051 #define OGDF_GRAPH_D_H
00052
00053
00054 #include <ogdf/basic/List.h>
00055
00056
00057 namespace ogdf {
00058
00059
00060
00061
00062
00063
00064 class OGDF_EXPORT Graph;
00065 class OGDF_EXPORT NodeElement;
00066 class OGDF_EXPORT EdgeElement;
00067 class OGDF_EXPORT AdjElement;
00068 class OGDF_EXPORT FaceElement;
00069 class OGDF_EXPORT GraphListBase;
00070 class OGDF_EXPORT ClusterElement;
00071
00072
00074
00079 class OGDF_EXPORT GraphElement {
00080 friend class Graph;
00081 friend class GraphListBase;
00082
00083 protected:
00084 GraphElement *m_next;
00085 GraphElement *m_prev;
00086
00087 OGDF_NEW_DELETE
00088 };
00089
00090
00092 class OGDF_EXPORT GraphListBase {
00093 protected:
00094 GraphElement *m_head;
00095 GraphElement *m_tail;
00096
00097 public:
00099 GraphListBase() { m_head = m_tail = 0; }
00100
00101 ~GraphListBase() { }
00102
00104 void pushBack(GraphElement *pX) {
00105 pX->m_next = 0;
00106 pX->m_prev = m_tail;
00107 if (m_head)
00108 m_tail = m_tail->m_next = pX;
00109 else
00110 m_tail = m_head = pX;
00111 }
00112
00114 void insertAfter(GraphElement *pX, GraphElement *pY) {
00115 pX->m_prev = pY;
00116 GraphElement *pYnext = pX->m_next = pY->m_next;
00117 pY->m_next = pX;
00118 if (pYnext) pYnext->m_prev = pX;
00119 else m_tail = pX;
00120 }
00121
00123 void insertBefore(GraphElement *pX, GraphElement *pY) {
00124 pX->m_next = pY;
00125 GraphElement *pYprev = pX->m_prev = pY->m_prev;
00126 pY->m_prev = pX;
00127 if (pYprev) pYprev->m_next = pX;
00128 else m_head = pX;
00129 }
00130
00132 void del(GraphElement *pX) {
00133 GraphElement *pxPrev = pX->m_prev, *pxNext = pX->m_next;
00134
00135 if (pxPrev)
00136 pxPrev->m_next = pxNext;
00137 else
00138 m_head = pxNext;
00139 if (pxNext)
00140 pxNext->m_prev = pxPrev;
00141 else
00142 m_tail = pxPrev;
00143 }
00144
00146 template<class LIST>
00147 void sort(const LIST &newOrder) {
00148 GraphElement *pPred = 0;
00149 typename LIST::const_iterator it = newOrder.begin();
00150 if (!it.valid()) return;
00151
00152 m_head = *it;
00153 for(; it.valid(); ++it) {
00154 GraphElement *p = *it;
00155 if ((p->m_prev = pPred) != 0) pPred->m_next = p;
00156 pPred = p;
00157 }
00158
00159 (m_tail = pPred)->m_next = 0;
00160 }
00161
00163 void reverse() {
00164 GraphElement *pX = m_head;
00165 m_head = m_tail;
00166 m_tail = pX;
00167 while(pX) {
00168 GraphElement *pY = pX->m_next;
00169 pX->m_next = pX->m_prev;
00170 pX = pX->m_prev = pY;
00171 }
00172 }
00173
00175 void swap(GraphElement *pX, GraphElement *pY) {
00176 if (pX->m_next == pY) {
00177 pX->m_next = pY->m_next;
00178 pY->m_prev = pX->m_prev;
00179 pY->m_next = pX;
00180 pX->m_prev = pY;
00181
00182 } else if(pY->m_next == pX) {
00183 pY->m_next = pX->m_next;
00184 pX->m_prev = pY->m_prev;
00185 pX->m_next = pY;
00186 pY->m_prev = pX;
00187
00188 } else {
00189 ::swap(pX->m_next,pY->m_next);
00190 ::swap(pX->m_prev,pY->m_prev);
00191 }
00192
00193 if(pX->m_prev)
00194 pX->m_prev->m_next = pX;
00195 else
00196 m_head = pX;
00197 if(pX->m_next)
00198 pX->m_next->m_prev = pX;
00199 else
00200 m_tail = pX;
00201
00202 if(pY->m_prev)
00203 pY->m_prev->m_next = pY;
00204 else
00205 m_head = pY;
00206 if(pY->m_next)
00207 pY->m_next->m_prev = pY;
00208 else
00209 m_tail = pY;
00210
00211 OGDF_ASSERT(consistencyCheck());
00212 }
00213
00214
00216 bool consistencyCheck() {
00217 if (m_head == 0) {
00218 return (m_tail == 0);
00219
00220 } else if (m_tail == 0) {
00221 return false;
00222
00223 } else {
00224 if (m_head->m_prev != 0)
00225 return false;
00226 if (m_tail->m_next != 0)
00227 return false;
00228
00229 GraphElement *pX = m_head;
00230 for(; pX; pX = pX->m_next) {
00231 if (pX->m_prev) {
00232 if (pX->m_prev->m_next != pX)
00233 return false;
00234 } else if(pX != m_head)
00235 return false;
00236
00237 if (pX->m_next) {
00238 if (pX->m_next->m_prev != pX)
00239 return false;
00240 } else if (pX != m_tail)
00241 return false;
00242 }
00243 }
00244
00245 return true;
00246 }
00247
00248 OGDF_NEW_DELETE
00249 };
00250
00251
00253
00256 template<class T> class GraphList : protected GraphListBase {
00257 public:
00259 GraphList() { }
00260
00261 ~GraphList() {
00262 if (m_head)
00263 OGDF_ALLOCATOR::deallocateList(sizeof(T), m_head,m_tail);
00264 }
00265
00267 T *begin () const { return (T *)m_head; }
00269 T *rbegin() const { return (T *)m_tail; }
00270
00272 bool empty() { return m_head; }
00273
00275 void pushBack(T *pX) {
00276 GraphListBase::pushBack(pX);
00277 }
00278
00280 void insertAfter(T *pX, T *pY) {
00281 GraphListBase::insertAfter(pX,pY);
00282 }
00283
00285 void insertBefore(T *pX, T *pY) {
00286 GraphListBase::insertBefore(pX,pY);
00287 }
00288
00290 void move(T *pX, GraphList<T> &L, T *pY, Direction dir) {
00291 GraphListBase::del(pX);
00292 if (dir == after)
00293 L.insertAfter(pX,pY);
00294 else
00295 L.insertBefore(pX,pY);
00296 }
00297
00299 void move(T *pX, GraphList<T> &L) {
00300 GraphListBase::del(pX);
00301 L.pushBack(pX);
00302 }
00303
00305 void moveAfter(T *pX, T *pY){
00306 GraphListBase::del(pX);
00307 insertAfter(pX,pY);
00308 }
00309
00311 void moveBefore(T *pX, T *pY){
00312 GraphListBase::del(pX);
00313 insertBefore(pX,pY);
00314 }
00315
00317 void del(T *pX) {
00318 GraphListBase::del(pX);
00319 delete pX;
00320 }
00321
00323 void delPure(T *pX) {
00324 GraphListBase::del(pX);
00325 }
00326
00328 void clear() {
00329 if (m_head) {
00330 OGDF_ALLOCATOR::deallocateList(sizeof(T),m_head,m_tail);
00331 m_head = m_tail = 0;
00332 }
00333 }
00334
00336 template<class T_LIST>
00337 void sort(const T_LIST &newOrder) {
00338 GraphListBase::sort(newOrder);
00339 }
00340
00341
00343 void reverse() {
00344 GraphListBase::reverse();
00345 }
00346
00348 void swap(T *pX, T *pY) {
00349 GraphListBase::swap(pX,pY);
00350 }
00351
00352
00354 bool consistencyCheck() {
00355 return GraphListBase::consistencyCheck();
00356 }
00357
00358
00359 OGDF_NEW_DELETE
00360 };
00361
00362
00363 typedef NodeElement *node;
00364 typedef EdgeElement *edge;
00365 typedef AdjElement *adjEntry;
00366
00367
00368
00370
00374 class OGDF_EXPORT AdjElement : private GraphElement {
00375 friend class Graph;
00376 friend class GraphListBase;
00377 friend class GraphList<AdjElement>;
00378
00379 AdjElement *m_twin;
00380 edge m_edge;
00381 node m_node;
00382 int m_id;
00383
00385 AdjElement(node v) : m_node(v) { }
00387 AdjElement(edge e, int id) : m_edge(e), m_id(id) { }
00388
00389 public:
00391 edge theEdge() const { return m_edge; }
00393 operator edge() const { return m_edge; }
00395 node theNode() const { return m_node; }
00396
00398 adjEntry twin() const { return m_twin; }
00399
00401 node twinNode() const { return m_twin->m_node; }
00402
00404 int index() const { return m_id; }
00405
00406
00407
00408
00410 adjEntry clockwiseFaceSucc() const { return m_twin->cyclicPred(); }
00412 adjEntry clockwiseFacePred() const { return cyclicSucc()->m_twin; }
00414 adjEntry counterClockwiseFaceSucc() const { return m_twin->cyclicSucc(); }
00416 adjEntry counterClockwiseFacePred() const { return cyclicPred()->m_twin; }
00417
00418
00420 adjEntry faceCycleSucc() const { return clockwiseFaceSucc(); }
00422 adjEntry faceCyclePred() const { return clockwiseFacePred(); }
00423
00424
00426 adjEntry succ() const { return (adjEntry)m_next; }
00428 adjEntry pred() const { return (adjEntry)m_prev; }
00429
00431 adjEntry cyclicSucc() const;
00433 adjEntry cyclicPred() const;
00434
00435 #ifdef OGDF_DEBUG
00436 const Graph *graphOf() const;
00437 #endif
00438
00439 OGDF_NEW_DELETE
00440 };
00441
00442
00444 class OGDF_EXPORT NodeElement : private GraphElement {
00445 friend class Graph;
00446 friend class GraphList<NodeElement>;
00447
00448 GraphList<AdjElement> m_adjEdges;
00449 int m_indeg;
00450 int m_outdeg;
00451 int m_id;
00452
00453 #ifdef OGDF_DEBUG
00454
00455 const Graph *m_pGraph;
00456 #endif
00457
00458
00459
00460 #ifdef OGDF_DEBUG
00461
00462
00467 NodeElement(const Graph *pGraph, int id) :
00468 m_indeg(0), m_outdeg(0), m_id(id), m_pGraph(pGraph) { }
00469 #else
00470 NodeElement(int id) : m_indeg(0), m_outdeg(0), m_id(id) { }
00471 #endif
00472
00473
00474 public:
00476 int index() const { return m_id; }
00477
00479 int indeg() const { return m_indeg; }
00481 int outdeg() const { return m_outdeg; }
00483 int degree() const { return m_indeg + m_outdeg; }
00484
00486 adjEntry firstAdj() const { return m_adjEdges.begin(); }
00488 adjEntry lastAdj () const { return m_adjEdges.rbegin(); }
00489
00491 node succ() const { return (node)m_next; }
00493 node pred() const { return (node)m_prev; }
00494
00495 #ifdef OGDF_DEBUG
00496
00497 const Graph *graphOf() const { return m_pGraph; }
00498 #endif
00499
00500 OGDF_NEW_DELETE
00501 };
00502
00503
00504 inline adjEntry AdjElement::cyclicSucc() const
00505 {
00506 return (m_next) ? (adjEntry)m_next : m_node->firstAdj();
00507 }
00508
00509 inline adjEntry AdjElement::cyclicPred() const
00510 {
00511 return (m_prev) ? (adjEntry)m_prev : m_node->lastAdj();
00512 }
00513
00514 inline bool test_forall_adj_edges(adjEntry &adj, edge &e)
00515 {
00516 if (adj) { e = adj->theEdge(); return true; }
00517 else return false;
00518 }
00519
00520
00521
00523 class OGDF_EXPORT EdgeElement : private GraphElement {
00524 friend class Graph;
00525 friend class GraphList<EdgeElement>;
00526
00527 node m_src;
00528 node m_tgt;
00529 AdjElement *m_adjSrc;
00530 AdjElement *m_adjTgt;
00531 int m_id;
00532
00534
00541 EdgeElement(node src, node tgt, AdjElement *adjSrc, AdjElement *adjTgt, int id) :
00542 m_src(src), m_tgt(tgt), m_adjSrc(adjSrc), m_adjTgt(adjTgt), m_id(id) { }
00543
00545
00550 EdgeElement(node src, node tgt, int id) :
00551 m_src(src), m_tgt(tgt), m_id(id) { }
00552
00553 public:
00555 int index() const { return m_id; }
00557 node source() const { return m_src; }
00559 node target() const { return m_tgt; }
00560
00562 adjEntry adjSource() const { return m_adjSrc; }
00564 adjEntry adjTarget() const { return m_adjTgt; }
00565
00567 node opposite(node v) const { return (v == m_src) ? m_tgt : m_src; }
00568
00569 bool isSelfLoop() const { return m_src == m_tgt; }
00570
00572 edge succ() const { return (edge)m_next; }
00574 edge pred() const { return (edge)m_prev; }
00575
00576 #ifdef OGDF_DEBUG
00577
00578 const Graph *graphOf() const { return m_src->graphOf(); }
00579 #endif
00580
00582 bool isIncident(node v) const { return v == m_src || v == m_tgt; }
00583
00585 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); }
00586
00587 OGDF_NEW_DELETE
00588 };
00589
00590
00591 #ifdef OGDF_DEBUG
00592 inline const Graph *AdjElement::graphOf() const {
00593 return m_node->graphOf();
00594 }
00595 #endif
00596
00597
00598 template<>inline bool doDestruction<node>(const node *) { return false; }
00599 template<>inline bool doDestruction<edge>(const edge *) { return false; }
00600 template<>inline bool doDestruction<adjEntry>(const adjEntry *) { return false; }
00601
00602 class NodeArrayBase;
00603 class EdgeArrayBase;
00604 class AdjEntryArrayBase;
00605 template<class T> class NodeArray;
00606 template<class T> class EdgeArray;
00607 template<class T> class AdjEntryArray;
00608 class OGDF_EXPORT GraphObserver;
00609
00610
00611
00612
00613
00614
00616 #define forall_nodes(v,G) for((v)=(G).firstNode(); (v); (v)=(v)->succ())
00617
00618 #define forall_rev_nodes(v,G) for((v)=(G).lastNode(); (v); (v)=(v)->pred())
00619
00621 #define forall_edges(e,G) for((e)=(G).firstEdge(); (e); (e)=(e)->succ())
00622
00623 #define forall_rev_edges(e,G) for((e)=(G).lastEdge(); (e); (e)=(e)->pred())
00624
00626 #define forall_adj(adj,v) for((adj)=(v)->firstAdj(); (adj); (adj)=(adj)->succ())
00627
00628 #define forall_rev_adj(adj,v) for((adj)=(v)->lastAdj(); (adj); (adj)=(adj)->pred())
00629
00631 #define forall_adj_edges(e,v)\
00632 for(ogdf::adjEntry ogdf_loop_var=(v)->firstAdj();\
00633 ogdf::test_forall_adj_edges(ogdf_loop_var,(e));\
00634 ogdf_loop_var=ogdf_loop_var->succ())
00635
00636
00638
00689 class OGDF_EXPORT Graph
00690 {
00691 GraphList<NodeElement> m_nodes;
00692 GraphList<EdgeElement> m_edges;
00693 int m_nNodes;
00694 int m_nEdges;
00695
00696 int m_nodeIdCount;
00697 int m_edgeIdCount;
00698
00699 int m_nodeArrayTableSize;
00700 int m_edgeArrayTableSize;
00701
00702 mutable ListPure<NodeArrayBase*> m_regNodeArrays;
00703 mutable ListPure<EdgeArrayBase*> m_regEdgeArrays;
00704 mutable ListPure<AdjEntryArrayBase*> m_regAdjArrays;
00705 mutable ListPure<GraphObserver*> m_regStructures;
00706
00707 GraphList<EdgeElement> m_hiddenEdges;
00708
00709 public:
00710
00711
00712
00713
00715 enum EdgeType {
00716 association = 0,
00717 generalization = 1,
00718 dependency = 2
00719 };
00720
00722 enum NodeType {
00723 vertex,
00724 dummy,
00725 generalizationMerger,
00726 generalizationExpander,
00727 highDegreeExpander,
00728 lowDegreeExpander,
00729 associationClass
00730 };
00731
00732
00734 Graph();
00735
00737
00742 Graph(const Graph &G);
00743
00744
00745 virtual ~Graph();
00746
00747
00752
00754 bool empty() const { return m_nNodes == 0; }
00755
00757 int numberOfNodes() const { return m_nNodes; }
00758
00760 int numberOfEdges() const { return m_nEdges; }
00761
00763 int maxNodeIndex() const { return m_nodeIdCount-1; }
00765 int maxEdgeIndex() const { return m_edgeIdCount-1; }
00767 int maxAdjEntryIndex() const { return (m_edgeIdCount<<1)-1; }
00768
00770 int nodeArrayTableSize() const { return m_nodeArrayTableSize; }
00772 int edgeArrayTableSize() const { return m_edgeArrayTableSize; }
00774 int adjEntryArrayTableSize() const { return m_edgeArrayTableSize << 1; }
00775
00777 node firstNode() const { return m_nodes.begin (); }
00779 node lastNode () const { return m_nodes.rbegin(); }
00780
00782 edge firstEdge() const { return m_edges.begin (); }
00784 edge lastEdge () const { return m_edges.rbegin(); }
00785
00787 node chooseNode() const;
00789 edge chooseEdge() const;
00790
00792 template<class NODELIST>
00793 void allNodes(NODELIST &nodes) const {
00794 nodes.clear();
00795 for (node v = m_nodes.begin(); v; v = v->succ())
00796 nodes.pushBack(v);
00797 }
00798
00800 template<class EDGELIST>
00801 void allEdges(EDGELIST &edges) const {
00802 edges.clear();
00803 for (edge e = m_edges.begin(); e; e = e->succ())
00804 edges.pushBack(e);
00805 }
00806
00808 template<class EDGELIST>
00809 void adjEdges(node v, EDGELIST &edges) const {
00810 edges.clear();
00811 edge e;
00812 forall_adj_edges(e,v)
00813 edges.pushBack(e);
00814 }
00815
00817 template<class ADJLIST>
00818 void adjEntries(node v, ADJLIST &entries) const {
00819 entries.clear();
00820 adjEntry adj;
00821 forall_adj(adj,v)
00822 entries.pushBack(adj);
00823 }
00824
00826 template<class EDGELIST>
00827 void inEdges(node v, EDGELIST &edges) const {
00828 edges.clear();
00829 edge e;
00830 forall_adj_edges(e,v)
00831 if (e->target() == v) edges.pushBack(e);
00832 }
00833
00835 template<class EDGELIST>
00836 void outEdges(node v, EDGELIST &edges) const {
00837 edges.clear();
00838 edge e;
00839 forall_adj_edges(e,v)
00840 if (e->source() == v) edges.pushBack(e);
00841 }
00842
00843
00845
00849
00851 node newNode();
00852
00854
00861 node newNode(int index);
00862
00864 edge newEdge(node v, node w);
00865
00867
00874 edge newEdge(node v, node w, int index);
00875
00877
00889 edge newEdge(adjEntry adjSrc, adjEntry adjTgt, Direction dir = ogdf::after);
00890
00892
00900 edge newEdge(node v, adjEntry adjTgt);
00901
00903
00911 edge newEdge(adjEntry adjSrc, node w);
00912
00913
00915
00919
00921 void delNode(node v);
00922
00924 void delEdge(edge e);
00925
00927 void clear();
00928
00929
00931
00939
00941
00946 void hideEdge(edge e);
00947
00949
00952 void restoreEdge(edge e);
00953
00955 void restoreAllEdges();
00956
00961
00962
00964
00970 virtual edge split(edge e);
00971
00973
00980 void unsplit(node u);
00981
00983
00991 virtual void unsplit(edge eIn, edge eOut);
00992
00994
01011 node splitNode(adjEntry adjStartLeft, adjEntry adjStartRight);
01012
01014 node contract(edge e);
01015
01016
01017
01018
01019 void move(edge e, adjEntry adjSrc, Direction dirSrc,
01020 adjEntry adjTgt, Direction dirTgt);
01021
01023
01026 void moveTarget(edge e, node w);
01027
01029
01033 void moveTarget(edge e, adjEntry adjTgt, Direction dir);
01034
01036
01039 void moveSource(edge e, node w);
01040
01042
01046 void moveSource(edge e, adjEntry adjSrc, Direction dir);
01047
01049
01050 edge searchEdge (node v, node w) const;
01051
01053 void reverseEdge(edge e);
01054
01056 void reverseAllEdges();
01057
01059
01062 template<class NODELIST>
01063 void collaps(NODELIST &nodes){
01064 node v = nodes.popFrontRet();
01065 while (!nodes.empty())
01066 {
01067 node w = nodes.popFrontRet();
01068 adjEntry adj = w->firstAdj();
01069 while (adj !=0)
01070 {
01071 adjEntry succ = adj->succ();
01072 edge e = adj->theEdge();
01073 if (e->source() == v || e->target() == v)
01074 delEdge(e);
01075 else if (e->source() == w)
01076 moveSource(e,v);
01077 else
01078 moveTarget(e,v);
01079 adj = succ;
01080 }
01081 delNode(w);
01082 }
01083 }
01084
01086
01089 template<class ADJ_ENTRY_LIST>
01090 void sort(node v, const ADJ_ENTRY_LIST &newOrder) {
01091 #ifdef OGDF_DEBUG
01092 typename ADJ_ENTRY_LIST::const_iterator it;
01093 for(it = newOrder.begin(); it.valid() ; ++it) {
01094 OGDF_ASSERT((*it)->theNode() == v);
01095 }
01096 #endif
01097 v->m_adjEdges.sort(newOrder);
01098 }
01099
01101 void reverseAdjEdges(node v) {
01102 v->m_adjEdges.reverse();
01103 }
01104
01106
01112 void moveAdj(adjEntry adjMove, Direction dir, adjEntry adjPos) {
01113 OGDF_ASSERT(adjMove->graphOf() == this && adjPos->graphOf() == this);
01114 OGDF_ASSERT(adjMove != 0 && adjPos != 0);
01115 GraphList<AdjElement> &adjList = adjMove->m_node->m_adjEdges;
01116 adjList.move(adjMove, adjList, adjPos, dir);
01117 }
01118
01120
01125 void moveAdjAfter(adjEntry adjMove, adjEntry adjAfter) {
01126 OGDF_ASSERT(adjMove->graphOf() == this && adjAfter->graphOf() == this);
01127 OGDF_ASSERT(adjMove != 0 && adjAfter != 0);
01128 adjMove->m_node->m_adjEdges.moveAfter(adjMove,adjAfter);
01129 }
01130
01132
01137 void moveAdjBefore(adjEntry adjMove, adjEntry adjBefore) {
01138 OGDF_ASSERT(adjMove->graphOf() == this && adjBefore->graphOf() == this);
01139 OGDF_ASSERT(adjMove != 0 && adjBefore != 0);
01140 adjMove->m_node->m_adjEdges.moveBefore(adjMove,adjBefore);
01141 }
01142
01144 void reverseAdjEdges();
01145
01147
01150 void swapAdjEdges(adjEntry adj1, adjEntry adj2) {
01151 OGDF_ASSERT(adj1->theNode() == adj2->theNode());
01152 OGDF_ASSERT(adj1->graphOf() == this);
01153
01154 adj1->theNode()->m_adjEdges.swap(adj1,adj2);
01155 }
01156
01157
01159
01163
01165 bool readGML(const char *fileName);
01166
01168 bool readGML(istream &is);
01169
01171 void writeGML(const char *fileName) const;
01172
01174 void writeGML(ostream &os) const;
01175
01177 bool readLEDAGraph(const char *fileName);
01178
01180 bool readLEDAGraph(istream &is);
01181
01182
01184
01188
01190
01198 int genus() const;
01199
01201 bool representsCombEmbedding() const {
01202 return (genus() == 0);
01203 }
01204
01206
01209 bool consistencyCheck() const;
01210
01211
01213
01219
01221 ListIterator<NodeArrayBase*> registerArray(NodeArrayBase *pNodeArray) const;
01223 ListIterator<EdgeArrayBase*> registerArray(EdgeArrayBase *pEdgeArray) const;
01225 ListIterator<AdjEntryArrayBase*> registerArray(AdjEntryArrayBase *pAdjArray) const;
01227 ListIterator<GraphObserver*> registerStructure(GraphObserver *pStructure) const;
01228
01230 void unregisterArray(ListIterator<NodeArrayBase*> it) const;
01232 void unregisterArray(ListIterator<EdgeArrayBase*> it) const;
01234 void unregisterArray(ListIterator<AdjEntryArrayBase*> it) const;
01236 void unregisterStructure(ListIterator<GraphObserver*> it) const;
01237
01238
01240
01264 void resetEdgeIdCount(int maxId);
01265
01266
01268
01272
01273
01278 Graph &operator=(const Graph &G);
01279
01280 OGDF_MALLOC_NEW_DELETE
01281
01283
01284 public:
01285
01287 static int nextPower2(int start, int idCount);
01288
01289
01290 protected:
01291 void construct(const Graph &G, NodeArray<node> &mapNode,
01292 EdgeArray<edge> &mapEdge);
01293
01294 void assign(const Graph &G, NodeArray<node> &mapNode,
01295 EdgeArray<edge> &mapEdge);
01296
01303 void constructInitByNodes(
01304 const Graph &G,
01305 const List<node> &nodes,
01306 NodeArray<node> &mapNode,
01307 EdgeArray<edge> &mapEdge);
01308
01309 void constructInitByActiveNodes(
01310 const List<node> &nodes,
01311 const NodeArray<bool> &activeNodes,
01312 NodeArray<node> &mapNode,
01313 EdgeArray<edge> &mapEdge);
01314
01315 private:
01316 void copy(const Graph &G, NodeArray<node> &mapNode,
01317 EdgeArray<edge> &mapEdge);
01318 void copy(const Graph &G);
01319
01320 edge createEdgeElement(node v, node w, adjEntry adjSrc, adjEntry adjTgt);
01321 node pureNewNode();
01322
01323
01324 void moveAdj(adjEntry adj, node w);
01325
01326 void reinitArrays();
01327 void reinitStructures();
01328 void resetAdjEntryIndex(int newIndex, int oldIndex);
01329
01330 bool readToEndOfLine(istream &is);
01331 };
01332
01333
01334
01336 class OGDF_EXPORT BucketSourceIndex : public BucketFunc<edge> {
01337 public:
01339 int getBucket(const edge &e) { return e->source()->index(); }
01340 };
01341
01343 class OGDF_EXPORT BucketTargetIndex : public BucketFunc<edge> {
01344 public:
01346 int getBucket(const edge &e) { return e->target()->index(); }
01347 };
01348
01349
01350 }
01351
01352 #endif
01353