COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/marci_list_graph.hh @ 9:a9ed3f1c2c63

Last change on this file since 9:a9ed3f1c2c63 was 9:a9ed3f1c2c63, checked in by marci, 17 years ago

marci

File size: 11.1 KB
Line 
1#ifndef MARCI_LIST_GRAPH_HH
2#define MARCI_LIST_GRAPH_HH
3
4#include <iostream>
5
6namespace marci {
7
8  class list_graph {
9    class node_item;
10    class edge_item;
11  public:
12    class node_iterator;
13    class each_node_iterator;
14    class edge_iterator;
15    class each_edge_iterator;
16    class out_edge_iterator;
17    class in_edge_iterator;
18    class sym_edge_iterator;
19  private:
20    int node_id;
21    int edge_id;
22
23    node_item* _first_node;
24    node_item* _last_node;
25
26    class node_item {
27      friend class list_graph;
28      friend class node_iterator;
29      friend class each_node_iterator;
30      friend class edge_iterator;
31      friend class each_edge_iterator;
32      friend class out_edge_iterator;
33      friend class in_edge_iterator;
34      friend class sym_edge_iterator;
35      friend std::ostream& operator<<(std::ostream& os, const node_iterator& i);
36      friend std::ostream& operator<<(std::ostream& os, const edge_iterator& i);
37      list_graph* G;
38      int id;
39      edge_item* _first_out_edge;
40      edge_item* _last_out_edge;
41      edge_item* _first_in_edge;
42      edge_item* _last_in_edge;
43      node_item* _next_node;
44      node_item* _prev_node;
45    public:
46      node_item() { }
47    };
48
49    class edge_item {
50      friend class list_graph;
51      friend class node_iterator;
52      friend class each_node_iterator;
53      friend class edge_iterator;
54      friend class each_edge_iterator;
55      friend class out_edge_iterator;
56      friend class in_edge_iterator;
57      friend class sym_edge_iterator;
58      friend std::ostream& operator<<(std::ostream& os, const edge_iterator& i);
59      list_graph* G;
60      int id;
61      node_item* _tail;
62      node_item* _head;
63      edge_item* _next_out;
64      edge_item* _prev_out;
65      edge_item* _next_in;
66      edge_item* _prev_in;
67    public:
68      edge_item() { }
69    };
70
71    node_item* _add_node() {
72      node_item* p=new node_item;
73      p->id=node_id++;
74      p->_first_out_edge=0;
75      p->_last_out_edge=0;
76      p->_first_in_edge=0;
77      p->_last_in_edge=0;
78      p->_prev_node=_last_node;
79      p->_next_node=0;
80      if (_last_node) _last_node->_next_node=p;
81      _last_node=p;
82      if (!_first_node) _first_node=p;
83      return p;
84    }
85
86    edge_item* _add_edge(node_item* _tail, node_item* _head) {
87      edge_item* e=new edge_item;
88      e->id=edge_id++;
89      e->_tail=_tail;
90      e->_head=_head;
91     
92      e->_prev_out=_tail->_last_out_edge;
93      if (_tail->_last_out_edge) (_tail->_last_out_edge)->_next_out=e;
94      _tail->_last_out_edge=e;
95      if (!_tail->_first_out_edge) _tail->_first_out_edge=e;
96       
97      e->_prev_in=_head->_last_in_edge;
98      if (_head->_last_in_edge) (_head->_last_in_edge)->_next_in=e;
99      _head->_last_in_edge=e;
100      if (!_head->_first_in_edge) { _head->_first_in_edge=e; }
101      return e;
102    }
103
104  public:
105
106    /* default constructor */
107
108    list_graph() : node_id(0), edge_id(0), _first_node(0), _last_node(0) { }
109   
110    /* functions to construct iterators from the graph, or from each other */
111
112    each_node_iterator first_node() { return each_node_iterator(_first_node); }
113    each_edge_iterator first_edge() {
114      node_item* v=_first_node;
115      edge_item* edge=v->_first_out_edge;
116      while (v && !edge) { v=v->_next_node; if (v) edge=v->_first_out_edge; }
117      return each_edge_iterator(v, edge);
118    }
119   
120    out_edge_iterator first_out_edge(const node_iterator& v) {
121      return out_edge_iterator(v);
122    }
123    in_edge_iterator first_in_edge(const node_iterator& v) {
124      return in_edge_iterator(v);
125    }
126    sym_edge_iterator first_sym_edge(const node_iterator& v) {
127      return sym_edge_iterator(v);
128    }
129    node_iterator tail(const edge_iterator& e) { return e.tail_node(); }
130    node_iterator head(const edge_iterator& e) { return e.head_node(); }
131
132    node_iterator a_node(const out_edge_iterator& e) { return e.a_node(); }
133    node_iterator a_node(const in_edge_iterator& e) { return e.a_node(); }
134    node_iterator a_node(const sym_edge_iterator& e) { return e.a_node(); }
135
136    node_iterator b_node(const out_edge_iterator& e) { return e.b_node(); }
137    node_iterator b_node(const in_edge_iterator& e) { return e.b_node(); }
138    node_iterator b_node(const sym_edge_iterator& e) { return e.b_node(); }
139
140    node_iterator invalid_node() { return node_iterator(); }
141    edge_iterator invalid_edge() { return edge_iterator(); }
142    out_edge_iterator invalid_out_edge() { return out_edge_iterator(); }
143    in_edge_iterator invalid_in_edge() { return in_edge_iterator(); }
144    sym_edge_iterator invalid_sym_edge() { return sym_edge_iterator(); }
145
146    /* same methods in other style */
147    /* for experimental purpose */
148
149    void get_first(each_node_iterator& v) { v=each_node_iterator(_first_node); }
150    void get_first(each_edge_iterator& e) { e=first_edge(); }
151    void get_first(out_edge_iterator& e, const node_iterator& v) {
152      e=out_edge_iterator(v);
153    }
154    void get_first(in_edge_iterator& e, const node_iterator& v) {
155      e=in_edge_iterator(v);
156    }
157    void get_first(sym_edge_iterator& e, const node_iterator& v) {
158      e=sym_edge_iterator(v);
159    }
160    void get_tail(node_iterator& n, const edge_iterator& e) { n=tail(e); }
161    void get_head(node_iterator& n, const edge_iterator& e) { n=head(e); }
162
163    void get_a_node(node_iterator& n, const out_edge_iterator& e) { n=e.a_node(); }
164    void get_a_node(node_iterator& n, const in_edge_iterator& e) { n=e.a_node(); }
165    void get_a_node(node_iterator& n, const sym_edge_iterator& e) { n=e.a_node(); }
166    void get_b_node(node_iterator& n, const out_edge_iterator& e) { n=e.b_node(); }
167    void get_b_node(node_iterator& n, const in_edge_iterator& e) { n=e.b_node(); }
168    void get_b_node(node_iterator& n, const sym_edge_iterator& e) { n=e.b_node(); }
169    void get_invalid(node_iterator& n) { n=node_iterator(); }
170    void get_invalid(edge_iterator& e) { e=edge_iterator(); }
171    void get_invalid(out_edge_iterator& e) { e=out_edge_iterator(); }
172    void get_invalid(in_edge_iterator& e) { e=in_edge_iterator(); }
173    void get_invalid(sym_edge_iterator& e) { e=sym_edge_iterator(); }
174
175
176    /* for getting id's of graph objects */
177    /* these are important for the implementation of property vectors */
178
179    int id(const node_iterator& v) { return v.node->id; }
180    int id(const edge_iterator& e) { return e.edge->id; }
181
182    /* adding nodes and edges */
183
184    node_iterator add_node() { return node_iterator(_add_node()); }
185    edge_iterator add_edge(const node_iterator& u, const node_iterator& v) {
186      return edge_iterator(_add_edge(u.node, v.node));
187    }
188
189    /* stream operations, for testing purpose */
190
191    friend std::ostream& operator<<(std::ostream& os, const node_iterator& i) {
192      os << i.node->id; return os;
193    }
194    friend std::ostream& operator<<(std::ostream& os, const edge_iterator& i) {
195      os << "(" << i.edge->_tail->id << "--" << i.edge->id << "->" << i.edge->_head->id << ")";
196      return os;
197    }
198
199    class node_iterator {
200      friend class list_graph;
201
202      friend class edge_iterator;
203      friend class out_edge_iterator;
204      friend class in_edge_iterator;
205      friend class sym_edge_iterator;
206    protected:
207      node_item* node;
208      friend int list_graph::id(const node_iterator& v);
209    public:
210      node_iterator() : node(0) { }
211      node_iterator(node_item* _node) : node(_node) { }
212      bool is_valid() { return (node!=0); }
213      friend bool operator==(const node_iterator& u, const node_iterator& v) {
214        return v.node==u.node;
215      }
216      friend bool operator!=(const node_iterator& u, const node_iterator& v) {
217        return v.node!=u.node;
218      }
219      friend std::ostream& operator<<(std::ostream& os, const node_iterator& i);
220    };
221   
222    class each_node_iterator : public node_iterator {
223      friend class list_graph;
224    public:
225      each_node_iterator() : node_iterator() { }
226      each_node_iterator(node_item* v) : node_iterator(v) { }
227      each_node_iterator& operator++() { node=node->_next_node; return *this; }
228    };
229
230    class edge_iterator {
231      friend class list_graph;
232     
233      friend class node_iterator;
234      friend class each_node_iterator;
235    protected:
236      edge_item* edge;
237      friend int list_graph::id(const edge_iterator& e);
238    public:
239      edge_iterator() : edge(0) { }
240      edge_iterator(edge_item* _edge) : edge(_edge) { }
241      bool is_valid() { return (edge!=0); }
242      friend bool operator==(const edge_iterator& u, const edge_iterator& v) {
243        return v.edge==u.edge;
244      }
245      friend bool operator!=(const edge_iterator& u, const edge_iterator& v) {
246        return v.edge!=u.edge;
247      }
248    protected:
249      node_iterator tail_node() const { return node_iterator(edge->_tail); }
250      node_iterator head_node() const { return node_iterator(edge->_head); }
251    public:
252      friend std::ostream& operator<<(std::ostream& os, const edge_iterator& i);
253    };
254   
255    class each_edge_iterator : public edge_iterator {
256      friend class list_graph;
257      node_item* v;
258    public:
259      each_edge_iterator() : edge_iterator(), v(0) { }
260      each_edge_iterator(node_item* _v, edge_item* _e) : edge_iterator(_e), v(_v) { }
261      each_edge_iterator& operator++() {
262        edge=edge->_next_out;
263        while (v && !edge) { v=v->_next_node; if (v) edge=v->_first_out_edge; }
264        return *this;
265      }
266    };
267   
268    class out_edge_iterator : public edge_iterator {
269      friend class list_graph;
270      node_item* v;
271    public:
272      out_edge_iterator() : edge_iterator(), v(0) { }
273    protected:
274      out_edge_iterator(const node_iterator& _v) : v(_v.node) { edge=v->_first_out_edge; }
275    public:
276      out_edge_iterator& operator++() { edge=edge->_next_out; return *this; }
277    protected:
278      node_iterator a_node() const { return node_iterator(v); }
279      node_iterator b_node() const {
280        return (edge->_tail==v) ? node_iterator(edge->_head) : node_iterator(v); }
281    };
282   
283    class in_edge_iterator : public edge_iterator {
284      friend class list_graph;
285      node_item* v;
286    public:
287      in_edge_iterator() : edge_iterator(), v(0) { }
288    protected:
289      in_edge_iterator(const node_iterator& _v) : v(_v.node) {
290        edge=v->_first_in_edge;
291      }
292    public:
293      in_edge_iterator& operator++() { edge=edge->_next_in; return *this; }
294    protected:
295      node_iterator a_node() const { return node_iterator(v); }
296      node_iterator b_node() const {
297        return (edge->_tail==v) ? node_iterator(edge->_head) : node_iterator(v); }
298    };
299
300    class sym_edge_iterator : public edge_iterator {
301      friend class list_graph;
302      bool out_or_in; //1 iff out, 0 iff in
303      node_item* v;
304    public:
305      sym_edge_iterator() : edge_iterator(), v(0) { }
306    protected:
307      sym_edge_iterator(const node_iterator& _v) : v(_v.node) {
308        out_or_in=1;
309        edge=v->_first_out_edge;
310        if (!edge) { edge=v->_first_in_edge; out_or_in=0; }
311      }
312    public:
313      sym_edge_iterator& operator++() {
314        if (out_or_in) {
315          edge=edge->_next_out;
316          if (!edge) { out_or_in=0; edge=v->_first_in_edge; }
317        } else {
318          edge=edge->_next_in;
319        }
320        return *this;
321      }
322    protected:
323      node_iterator a_node() const { return node_iterator(v); }
324      node_iterator b_node() const {
325        return (edge->_tail==v) ? node_iterator(edge->_head) : node_iterator(v); }
326    };
327
328  };
329
330
331
332} //namespace marci
333
334#endif //MARCI_LIST_GRAPH_HH
Note: See TracBrowser for help on using the repository browser.