Open
Graph Drawing
Framework

 v.2012.05
 

Graph_d.h
Go to the documentation of this file.
00001 /*
00002  * $Revision: 2299 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2012-05-07 15:57:08 +0200 (Mon, 07 May 2012) $ 
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 // in embedded graphs, adjacency lists are given in clockwise order.
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 }; // class GraphElement
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     // destruction
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 }; // class GraphListBase
00250 
00251 
00253 
00256 template<class T> class GraphList : protected GraphListBase {
00257 public:
00259     GraphList() { }
00260     // destruction (deletes all elements)
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 }; // class GraphList<T>
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     // traversing faces in clockwise (resp. counter-clockwise) order
00407     // (if face is an interior face)
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     // default is traversing faces in clockwise order
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 }; // class AdjElement
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     // we store the graph containing this node for debugging purposes
00455     const Graph *m_pGraph; 
00456 #endif
00457 
00458 
00459     // construction
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 }; // class NodeElement
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; // The (unique) index of the node.
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     // Returns true iff the edge is a self-loop (source node = target node).
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 }; // class EdgeElement
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 // iteration macros
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     // enumerations
00712     //
00713 
00715     enum EdgeType {
00716         association = 0,
00717         generalization = 1,
00718         dependency = 2
00719     }; // should be more flexible, standard, dissect, expand
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     // destruction
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     // moves edge e to adjacency list of owner(adjSrc) inserting it before
01017     // or after adjSrc, and to owner(adjTgt) inserting it before or after
01018     // adjTgt; e is afterwards an edge from owner(adjSrc) to owner(adjTgt)
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     //  If no such edge exists, 0 is returned.
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     // moves adjacency entry to node w
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 }; // class Graph
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 } //namespace 
01351 
01352 #endif
01353