cgv
Loading...
Searching...
No Matches
adjacency_list.h
1#pragma once
2#include<vector>
3#include<assert.h>
4
5
6namespace cgv{
7 namespace math{
8
9
10//a basic graph edge type
11struct edge
12{
13 //index of start and end vertex
14 unsigned start,end;
15};
16
17
18struct weighted_edge : public edge
19{
21 double weight;
22 int flag;
23
26 weighted_edge(double w) : weight(w) {}
27};
28
29//a basic graph node type
30template <typename ET>
31struct vertex
32{
33 typedef typename ET edge_type;
34 //incident edges
35 std::vector<edge_type> edges;
36
37 unsigned nedges()
38 {
39 return edges.size();
40 }
41
42};
43
44
72template<typename v_type >
74{
75public:
76 typedef typename v_type vertex_type;
77 typedef typename v_type::edge_type edge_type;
78
79
81 std::vector<vertex_type> *vertices;
84
85
87 {
88 vertices = NULL;
89 directed = true;
90 }
91
94 adjacency_list(const unsigned vnum, bool directed=true) : directed(directed)
95 {
96 vertices = new std::vector<vertex_type>(vnum);
97 this->directed = directed;
98 }
99
100
101
104 {
105 if (vertices)
106 delete vertices;
107 directed = al.is_directed();
108 vertices = new std::vector<vertex_type>(*(al.vertices));
109 }
110
113 {
114 if(&al == this)
115 return *this;
116 if (vertices)
117 delete vertices;
118 directed = al.is_directed();
119 vertices = new std::vector<vertex_type>(*(al.vertices));
120 return *this;
121 }
122
125 {
126 if(vertices)
127 delete vertices;
128 }
129
131 void resize(const unsigned& vnum)
132 {
133 if(!vertices)
134 vertices = new std::vector<vertex_type>(vnum);
135 else
136 {
138 vertices->resize(vnum);
139 }
140 }
141
142 // clear graph
143 void clear()
144 {
145 if(vertices)
146 {
147 delete vertices;
148 vertices = NULL;
149 }
150 }
151
152
154 const unsigned nverts() const
155 {
156 assert(vertices != NULL);
157 return vertices->size();
158 }
159
162 {
163 for(unsigned vi = 0; vi < nverts(); vi++)
164 {
165 vertex(vi).edges.clear();
166 }
167 }
168
170 vertex_type& vertex(unsigned i)
171 {
172 return (*vertices)[i];
173 }
174
176 const vertex_type& vertex(unsigned i)const
177 {
178 return (*vertices)[i];
179 }
180
181
182
184 bool is_directed() const
185 {
186 return directed;
187 }
188
189
191 bool edge_exists(int start, int end) const
192 {
193 for (unsigned i=0; i < vertex(start).edges.size(); i++)
194 {
195 if(vertex(start).edges[i].end == end)
196 {
197 //std::cout<<"Edge already in list"<<std::endl;
198 return true;
199 }
200 }
201 return false;
202 }
203
204
205
207 bool add_edge(const edge_type& e)
208 {
209
210 if(edge_exists(e.start, e.end))
211 return false;
212
213
214 if( e.start < nverts() && e.end < nverts())
215 {
216
217
218
219 (*vertices)[e.start].edges.push_back(e);
220
221 if(!directed)
222 {
223 edge_type e2=e;
224 e2.start = e.end;
225 e2.end = e.start;
226 (*vertices)[e.end].edges.push_back(e2);
227 }
228 return true;
229 }
230 return false;
231 }
232
233
235 bool add_edge(unsigned int start, unsigned int end)
236 {
237
238 if(edge_exists(start, end))
239 return false;
240
241
242 if( start < nverts() && end < vertices->size())
243 {
244
245 edge_type e;
246 e.start=start;
247 e.end = end;
248
249
250 (*vertices)[start].edges.push_back(e);
251
252 if(!directed)
253 {
254 edge_type e2;
255 e2.start=end;
256 e2.end = start;
257
258 (*vertices)[end].edges.push_back(e2);
259 }
260 return true;
261 }
262 return false;
263 }
264
266 void add_vertex(const vertex_type& v)
267 {
268 vertices->push_back(v);
269 }
270
271 /*/// adds an edge to the list
272 void add_edge(unsigned start,unsigned end,const edge_type& e)
273 {
274 if(edge_exists(start, end))
275 return false;
276
277
278 if( start < vertices->size() && end < vertices->size())
279 {
280
281 edge_type e;
282 e.start = start;
283 e.end = end;
284
285
286 (*vertices)[start].edges.push_back(e);
287
288 if(!directed)
289 {
290 edge_type e2;
291 e2.start = end;
292 e2.end = start;
293
294 (*vertices)[end].edges.push_back(e);
295 }
296 return true;
297 }
298 return false;
299 }*/
300
301/* /// adds an vertex with n zero filled edges to the list
302 void add(int n){
303
304 vertex v;
305 for(int i=0;i<n;i++){
306 edge a;
307 a.start = 0;
308 a.target = 0;
309 v.edges.push_back(a);
310 }
311 vertices->push_back(v);
312
313 }
314
316 void add(vertex v){
317 std::cout<<"not tested"<<std::endl;
318 vertices->push_back(v);
319 }
320
321
322
323
325 bool contains(edge e){
326
327 for (std::vector<vertex>::iterator it = vertices.begin(); it != vertices.target(); ++it) {
328 for (std::vector<vertex>::iterator i = it.edges.begin(); i != it.edges.target(); ++i) {
329 if ( e == *i )
330 return true;
331 }
332 }
333 return false;
334 }
335
337 bool contains(vertex v){
338
339 for (unsigned int i = 0; i < vertices->size(); i ++) {
340 if ( v == (*vertices)[i])
341 return true;
342 }
343 return false;
344 }
345
346
347
348
349 // outputs the list as String
350 void to_String(){
351 for (unsigned int i = 0; i < vertices->size(); i++){
352 std::cout<<i<<":[ "; // index of Vertex
353 for (unsigned int j = 0 ; j < (*vertices)[i].edges.size();j++){
354 std::cout<<(*vertices)[i].edges[j].start << "," << (*vertices)[i].edges[j].target << " "; // start and end of edges
355 }
356 std::cout<<"]"<<std::endl;
357 }
358 }
359
360
361
363 void remove(int start, int target){
364
365 for (unsigned int i = 0;i< (*vertices)[start].edges.size(); i++){
366 if((*vertices)[start].edges[i].target == target){
367 std::vector<edge>::iterator it = (*vertices)[start].edges.begin() + i;
368 (*vertices)[start].edges.erase(it);
369 }
370 }
371 }
372
374 void remove(vertex e){
375 std::cout<<"not implemented"<<std::endl;
376 }
377
379 void remove(int n){
380 // delete edges to n (all from n are deleted itself)
381 for(unsigned int i = 0; i< vertices->size(); i++){
382 for (unsigned int j = 0;j< (*vertices)[i].edges.size(); j++){
383 if((*vertices)[i].edges[j].target == n){
384 std::vector<edge>::iterator it = (*vertices)[i].edges.begin() + j;
385 (*vertices)[i].edges.erase(it);
386 }
387 // and decrese all edges with start or end > n
388 if((*vertices)[i].edges[j].target > n){
389 (*vertices)[i].edges[j].target -= 1;
390 }
391 if((*vertices)[i].edges[j].start > n){
392 (*vertices)[i].edges[j].start -= 1;
393 }
394 }
395 }
396
397 std::vector<vertex>::iterator it = vertices->begin() + n;
398 vertices->erase(it);
399
400
401 }*/
402
403};
404
405typedef adjacency_list<vertex<edge> > base_graph;
406typedef adjacency_list<vertex<weighted_edge> > weighted_graph;
407
408
409
410 }
411}
A graph represented in an adjacency list.
const vertex_type & vertex(unsigned i) const
access const vertex i
virtual ~adjacency_list()
destructor of adjacency_list
adjacency_list & operator=(const adjacency_list &al)
assignment operator
bool add_edge(const edge_type &e)
adds an edge to the list definded by the start and end vertex
bool add_edge(unsigned int start, unsigned int end)
adds an edge to the list definded by the start and end vertex
adjacency_list(const unsigned vnum, bool directed=true)
creates a graph with vnum vertices and zero edges the graph is directed if the flag directed is true
std::vector< vertex_type > * vertices
vertices
vertex_type & vertex(unsigned i)
access vertex i
const unsigned nverts() const
return number of vertices
void resize(const unsigned &vnum)
resize number of vertices, all edge data is removed
void remove_all_edges()
removes all edges
bool is_directed() const
returns true if the graph is a directed one
bool directed
flag indicating a directed/undirected graph
adjacency_list(const adjacency_list &al)
copy constructor
bool edge_exists(int start, int end) const
checks if edge is already in list
void add_vertex(const vertex_type &v)
add new vertex to graph
the cgv namespace
Definition print.h:11
weighted_edge()
standard constructor
double weight
edge weight