COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/lemon/list_graph.h @ 946:c94ef40a22ce

Last change on this file since 946:c94ef40a22ce was 946:c94ef40a22ce, checked in by Mihaly Barasz, 20 years ago

The graph_factory branch (@ 1321) has been merged to trunk.

File size: 6.2 KB
RevLine 
[946]1// -*- c++ -*-
[395]2
[921]3#ifndef LEMON_LIST_GRAPH_H
4#define LEMON_LIST_GRAPH_H
[395]5
[946]6#include <lemon/erasable_graph_extender.h>
7#include <lemon/clearable_graph_extender.h>
8#include <lemon/extendable_graph_extender.h>
[395]9
[946]10#include <lemon/idmappable_graph_extender.h>
[395]11
[946]12#include <lemon/iterable_graph_extender.h>
[395]13
[946]14#include <lemon/alteration_observer_registry.h>
[782]15
[946]16#include <lemon/default_map.h>
[782]17
18
[921]19namespace lemon {
[395]20
[946]21  class ListGraphBase {
[406]22
[946]23    struct NodeT {
[397]24      int first_in,first_out;
25      int prev, next;
[395]26    };
[946]27 
28    struct EdgeT {
[397]29      int head, tail;
30      int prev_in, prev_out;
31      int next_in, next_out;
[395]32    };
33
34    std::vector<NodeT> nodes;
[946]35
[397]36    int first_node;
[946]37
[397]38    int first_free_node;
[946]39
[395]40    std::vector<EdgeT> edges;
[946]41
[397]42    int first_free_edge;
[395]43   
[782]44  public:
[395]45   
[946]46    typedef ListGraphBase Graph;
[397]47   
[946]48    class Node {
49      friend class Graph;
50    protected:
[395]51
[946]52      int id;
53      Node(int pid) { id = pid;}
[395]54
[946]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    };
[782]62
[946]63    class Edge {
64      friend class Graph;
65    protected:
[782]66
[946]67      int id;
68      Edge(int pid) { id = pid;}
[395]69
[946]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()
[782]81      : nodes(), first_node(-1),
82        first_free_node(-1), edges(), first_free_edge(-1) {}
83
[395]84   
[695]85    ///it possible to avoid the superfluous memory allocation.
86    void reserveEdge(int n) { edges.reserve(n); };
87   
[813]88    /// Maximum node ID.
89   
90    /// Maximum node ID.
91    ///\sa id(Node)
92    int maxNodeId() const { return nodes.size()-1; }
[946]93
[813]94    /// Maximum edge ID.
95   
96    /// Maximum edge ID.
97    ///\sa id(Edge)
98    int maxEdgeId() const { return edges.size()-1; }
[395]99
[946]100    Node tail(Edge e) const { return edges[e.id].tail; }
101    Node head(Edge e) const { return edges[e.id].head; }
[395]102
103
[946]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
[813]147   
[946]148    static int id(Node v) { return v.id; }
149    static int id(Edge e) { return e.id; }
[395]150
[397]151    /// Adds a new node to the graph.
152
[813]153    /// \warning It adds the new node to the front of the list.
[397]154    /// (i.e. the lastly added node becomes the first.)
[946]155    Node addNode() {     
[397]156      int n;
157     
[946]158      if(first_free_node==-1) {
159        n = nodes.size();
160        nodes.push_back(NodeT());
161      } else {
[397]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     
[946]173      return Node(n);
[395]174    }
175   
176    Edge addEdge(Node u, Node v) {
[946]177      int n;     
178
179      if (first_free_edge == -1) {
180        n = edges.size();
181        edges.push_back(EdgeT());
182      } else {
[397]183        n = first_free_edge;
184        first_free_edge = edges[n].next_in;
185      }
186     
[946]187      edges[n].tail = u.id;
188      edges[n].head = v.id;
[395]189
[946]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     
[397]200      edges[n].prev_in = edges[n].prev_out = -1;
201       
[946]202      nodes[u.id].first_out = nodes[v.id].first_in = n;
[397]203
[946]204      return Edge(n);
[395]205    }
[774]206   
[946]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;
[395]222
[774]223    }
224   
[946]225    void erase(const Edge& edge) {
226      int n = edge.id;
[397]227     
[946]228      if(edges[n].next_in!=-1) {
[397]229        edges[edges[n].next_in].prev_in = edges[n].prev_in;
[946]230      }
231
232      if(edges[n].prev_in!=-1) {
[397]233        edges[edges[n].prev_in].next_in = edges[n].next_in;
[946]234      } else {
235        nodes[edges[n].head].first_in = edges[n].next_in;
236      }
237
[397]238     
[946]239      if(edges[n].next_out!=-1) {
[397]240        edges[edges[n].next_out].prev_out = edges[n].prev_out;
[946]241      }
242
243      if(edges[n].prev_out!=-1) {
[397]244        edges[edges[n].prev_out].next_out = edges[n].next_out;
[946]245      } else {
246        nodes[edges[n].tail].first_out = edges[n].next_out;
247      }
[397]248     
249      edges[n].next_in = first_free_edge;
[695]250      first_free_edge = n;     
[397]251
252    }
253
254    void clear() {
[782]255      edges.clear();
256      nodes.clear();
[946]257      first_node = first_free_node = first_free_edge = -1;
[937]258    }
259
[919]260  };
[909]261
[946]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;
[400]269
[946]270  typedef ErasableListGraphBase ListGraph;
[400]271
[946]272}
[400]273
[782]274
[946]275 
[400]276
[946]277#endif
Note: See TracBrowser for help on using the repository browser.