src/lemon/list_graph.h
author klao
Wed, 27 Oct 2004 22:38:50 +0000
changeset 946 c94ef40a22ce
parent 937 d4e911acef3d
child 948 bc86b64f958e
permissions -rw-r--r--
The graph_factory branch (@ 1321) has been merged to trunk.
     1 // -*- c++ -*-
     2 
     3 #ifndef LEMON_LIST_GRAPH_H
     4 #define LEMON_LIST_GRAPH_H
     5 
     6 #include <lemon/erasable_graph_extender.h>
     7 #include <lemon/clearable_graph_extender.h>
     8 #include <lemon/extendable_graph_extender.h>
     9 
    10 #include <lemon/idmappable_graph_extender.h>
    11 
    12 #include <lemon/iterable_graph_extender.h>
    13 
    14 #include <lemon/alteration_observer_registry.h>
    15 
    16 #include <lemon/default_map.h>
    17 
    18 
    19 namespace lemon {
    20 
    21   class ListGraphBase {
    22 
    23     struct NodeT {
    24       int first_in,first_out;
    25       int prev, next;
    26     };
    27  
    28     struct EdgeT {
    29       int head, tail;
    30       int prev_in, prev_out;
    31       int next_in, next_out;
    32     };
    33 
    34     std::vector<NodeT> nodes;
    35 
    36     int first_node;
    37 
    38     int first_free_node;
    39 
    40     std::vector<EdgeT> edges;
    41 
    42     int first_free_edge;
    43     
    44   public:
    45     
    46     typedef ListGraphBase Graph;
    47     
    48     class Node {
    49       friend class Graph;
    50     protected:
    51 
    52       int id;
    53       Node(int pid) { id = pid;}
    54 
    55     public:
    56       Node() {}
    57       Node (Invalid) { id = -1; }
    58       bool operator==(const Node& node) const {return id == node.id;}
    59       bool operator!=(const Node& node) const {return id != node.id;}
    60       bool operator<(const Node& node) const {return id < node.id;}
    61     };
    62 
    63     class Edge {
    64       friend class Graph;
    65     protected:
    66 
    67       int id;
    68       Edge(int pid) { id = pid;}
    69 
    70     public:
    71       Edge() {}
    72       Edge (Invalid) { id = -1; }
    73       bool operator==(const Edge& edge) const {return id == edge.id;}
    74       bool operator!=(const Edge& edge) const {return id != edge.id;}
    75       bool operator<(const Edge& edge) const {return id < edge.id;}
    76     };
    77 
    78 
    79 
    80     ListGraphBase()
    81       : nodes(), first_node(-1),
    82 	first_free_node(-1), edges(), first_free_edge(-1) {}
    83 
    84     
    85     ///it possible to avoid the superfluous memory allocation.
    86     void reserveEdge(int n) { edges.reserve(n); };
    87     
    88     /// Maximum node ID.
    89     
    90     /// Maximum node ID.
    91     ///\sa id(Node)
    92     int maxNodeId() const { return nodes.size()-1; } 
    93 
    94     /// Maximum edge ID.
    95     
    96     /// Maximum edge ID.
    97     ///\sa id(Edge)
    98     int maxEdgeId() const { return edges.size()-1; }
    99 
   100     Node tail(Edge e) const { return edges[e.id].tail; }
   101     Node head(Edge e) const { return edges[e.id].head; }
   102 
   103 
   104     void first(Node& node) const { 
   105       node.id = first_node;
   106     }
   107 
   108     void next(Node& node) const {
   109       node.id = nodes[node.id].next;
   110     }
   111 
   112 
   113     void first(Edge& e) const { 
   114       int n;
   115       for(n = first_node; 
   116 	  n!=-1 && nodes[n].first_in == -1; 
   117 	  n = nodes[n].next);
   118       e.id = (n == -1) ? -1 : nodes[n].first_in;
   119     }
   120 
   121     void next(Edge& edge) const {
   122       if (edges[edge.id].next_in != -1) {
   123 	edge.id = edges[edge.id].next_in;
   124       } else {
   125 	int n;
   126 	for(n = nodes[edges[edge.id].head].next;
   127 	  n!=-1 && nodes[n].first_in == -1; 
   128 	  n = nodes[n].next);
   129 	edge.id = (n == -1) ? -1 : nodes[n].first_in;
   130       }      
   131     }
   132 
   133     void firstOut(Edge &e, const Node& v) const {
   134       e.id = nodes[v.id].first_out;
   135     }
   136     void nextOut(Edge &e) const {
   137       e.id=edges[e.id].next_out;
   138     }
   139 
   140     void firstIn(Edge &e, const Node& v) const {
   141       e.id = nodes[v.id].first_in;
   142     }
   143     void nextIn(Edge &e) const {
   144       e.id=edges[e.id].next_in;
   145     }
   146 
   147     
   148     static int id(Node v) { return v.id; }
   149     static int id(Edge e) { return e.id; }
   150 
   151     /// Adds a new node to the graph.
   152 
   153     /// \warning It adds the new node to the front of the list.
   154     /// (i.e. the lastly added node becomes the first.)
   155     Node addNode() {     
   156       int n;
   157       
   158       if(first_free_node==-1) {
   159 	n = nodes.size();
   160 	nodes.push_back(NodeT());
   161       } else {
   162 	n = first_free_node;
   163 	first_free_node = nodes[n].next;
   164       }
   165       
   166       nodes[n].next = first_node;
   167       if(first_node != -1) nodes[first_node].prev = n;
   168       first_node = n;
   169       nodes[n].prev = -1;
   170       
   171       nodes[n].first_in = nodes[n].first_out = -1;
   172       
   173       return Node(n);
   174     }
   175     
   176     Edge addEdge(Node u, Node v) {
   177       int n;      
   178 
   179       if (first_free_edge == -1) {
   180 	n = edges.size();
   181 	edges.push_back(EdgeT());
   182       } else {
   183 	n = first_free_edge;
   184 	first_free_edge = edges[n].next_in;
   185       }
   186       
   187       edges[n].tail = u.id; 
   188       edges[n].head = v.id;
   189 
   190       edges[n].next_out = nodes[u.id].first_out;
   191       if(nodes[u.id].first_out != -1) {
   192 	edges[nodes[u.id].first_out].prev_out = n;
   193       }
   194       
   195       edges[n].next_in = nodes[v.id].first_in;
   196       if(nodes[v.id].first_in != -1) {
   197 	edges[nodes[v.id].first_in].prev_in = n;
   198       }
   199       
   200       edges[n].prev_in = edges[n].prev_out = -1;
   201 	
   202       nodes[u.id].first_out = nodes[v.id].first_in = n;
   203 
   204       return Edge(n);
   205     }
   206     
   207     void erase(const Node& node) {
   208       int n = node.id;
   209       
   210       if(nodes[n].next != -1) {
   211 	nodes[nodes[n].next].prev = nodes[n].prev;
   212       }
   213       
   214       if(nodes[n].prev != -1) {
   215 	nodes[nodes[n].prev].next = nodes[n].next;
   216       } else {
   217 	first_node = nodes[n].next;
   218       }
   219       
   220       nodes[n].next = first_free_node;
   221       first_free_node = n;
   222 
   223     }
   224     
   225     void erase(const Edge& edge) {
   226       int n = edge.id;
   227       
   228       if(edges[n].next_in!=-1) {
   229 	edges[edges[n].next_in].prev_in = edges[n].prev_in;
   230       }
   231 
   232       if(edges[n].prev_in!=-1) {
   233 	edges[edges[n].prev_in].next_in = edges[n].next_in;
   234       } else {
   235 	nodes[edges[n].head].first_in = edges[n].next_in;
   236       }
   237 
   238       
   239       if(edges[n].next_out!=-1) {
   240 	edges[edges[n].next_out].prev_out = edges[n].prev_out;
   241       } 
   242 
   243       if(edges[n].prev_out!=-1) {
   244 	edges[edges[n].prev_out].next_out = edges[n].next_out;
   245       } else {
   246 	nodes[edges[n].tail].first_out = edges[n].next_out;
   247       }
   248       
   249       edges[n].next_in = first_free_edge;
   250       first_free_edge = n;      
   251 
   252     }
   253 
   254     void clear() {
   255       edges.clear();
   256       nodes.clear();
   257       first_node = first_free_node = first_free_edge = -1;
   258     }
   259 
   260   };
   261 
   262   typedef AlterableGraphExtender<ListGraphBase> AlterableListGraphBase;
   263   typedef IterableGraphExtender<AlterableListGraphBase> IterableListGraphBase;
   264   typedef IdMappableGraphExtender<IterableListGraphBase> IdMappableListGraphBase;
   265   typedef DefaultMappableGraphExtender<IdMappableListGraphBase> MappableListGraphBase;
   266   typedef ExtendableGraphExtender<MappableListGraphBase> ExtendableListGraphBase;
   267   typedef ClearableGraphExtender<ExtendableListGraphBase> ClearableListGraphBase;
   268   typedef ErasableGraphExtender<ClearableListGraphBase> ErasableListGraphBase;
   269 
   270   typedef ErasableListGraphBase ListGraph;
   271 
   272 }
   273 
   274 
   275   
   276 
   277 #endif