Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

GraphList.h
Go to the documentation of this file.
1 
32 #pragma once
33 
34 #include <ogdf/basic/Array.h>
35 #include <ogdf/basic/List.h>
37 
38 namespace ogdf {
39 
40 class Graph;
41 class ClusterGraph;
42 class ConstCombinatorialEmbedding;
43 class CombinatorialEmbedding;
44 
45 namespace internal {
46 
47 class OGDF_EXPORT GraphListBase;
48 
50 
56  friend class ogdf::Graph;
57  friend class GraphListBase;
58 
59 protected:
60  GraphElement* m_next = nullptr;
61  GraphElement* m_prev = nullptr;
62 
64 };
65 
68 protected:
69  int m_size;
72 
73 public:
76  m_head = m_tail = nullptr;
77  m_size = 0;
78  }
79 
82 
84  int size() const { return m_size; }
85 
87  bool empty() const { return m_size == 0; }
88 
90  void pushBack(GraphElement* pX) {
91  pX->m_next = nullptr;
92  pX->m_prev = m_tail;
93  if (m_head) {
94  m_tail = m_tail->m_next = pX;
95  } else {
96  m_tail = m_head = pX;
97  }
98  ++m_size;
99  }
100 
103  pX->m_prev = pY;
104  GraphElement* pYnext = pX->m_next = pY->m_next;
105  pY->m_next = pX;
106  if (pYnext) {
107  pYnext->m_prev = pX;
108  } else {
109  m_tail = pX;
110  }
111  ++m_size;
112  }
113 
116  pX->m_next = pY;
117  GraphElement* pYprev = pX->m_prev = pY->m_prev;
118  pY->m_prev = pX;
119  if (pYprev) {
120  pYprev->m_next = pX;
121  } else {
122  m_head = pX;
123  }
124  ++m_size;
125  }
126 
128  void del(GraphElement* pX) {
129  GraphElement *pxPrev = pX->m_prev, *pxNext = pX->m_next;
130 
131  if (pxPrev) {
132  pxPrev->m_next = pxNext;
133  } else {
134  m_head = pxNext;
135  }
136  if (pxNext) {
137  pxNext->m_prev = pxPrev;
138  } else {
139  m_tail = pxPrev;
140  }
141  m_size--;
142  }
143 
145  template<class LIST>
146  void sort(const LIST& newOrder) {
147  using std::begin;
148  using std::end;
149  sort(begin(newOrder), end(newOrder));
150  }
151 
153  template<class IT>
154  void sort(IT begin, IT end) {
155  if (begin == end) {
156  return;
157  }
158  m_head = *begin;
159  GraphElement* pPred = nullptr;
160  for (auto it = begin; it != end; ++it) {
161  GraphElement* p = *it;
162  if ((p->m_prev = pPred) != nullptr) {
163  pPred->m_next = p;
164  }
165  pPred = p;
166  }
167  (m_tail = pPred)->m_next = nullptr;
168  }
169 
171  void reverse() {
172  GraphElement* pX = m_head;
173  m_head = m_tail;
174  m_tail = pX;
175  while (pX) {
176  GraphElement* pY = pX->m_next;
177  pX->m_next = pX->m_prev;
178  pX = pX->m_prev = pY;
179  }
180  }
181 
183  void swap(GraphElement* pX, GraphElement* pY) {
184  if (pX->m_next == pY) {
185  pX->m_next = pY->m_next;
186  pY->m_prev = pX->m_prev;
187  pY->m_next = pX;
188  pX->m_prev = pY;
189 
190  } else if (pY->m_next == pX) {
191  pY->m_next = pX->m_next;
192  pX->m_prev = pY->m_prev;
193  pX->m_next = pY;
194  pY->m_prev = pX;
195 
196  } else {
197  std::swap(pX->m_next, pY->m_next);
198  std::swap(pX->m_prev, pY->m_prev);
199  }
200 
201  if (pX->m_prev) {
202  pX->m_prev->m_next = pX;
203  } else {
204  m_head = pX;
205  }
206  if (pX->m_next) {
207  pX->m_next->m_prev = pX;
208  } else {
209  m_tail = pX;
210  }
211 
212  if (pY->m_prev) {
213  pY->m_prev->m_next = pY;
214  } else {
215  m_head = pY;
216  }
217  if (pY->m_next) {
218  pY->m_next->m_prev = pY;
219  } else {
220  m_tail = pY;
221  }
222 
223 #ifdef OGDF_DEBUG
224  consistencyCheck();
225 #endif
226  }
227 
229  template<class RNG>
230  void permute(RNG& rng) {
231  Array<GraphElement*> A(m_size + 2);
232  A[0] = A[m_size + 1] = nullptr;
233 
234  int i = 1;
235  GraphElement* pX;
236  for (pX = m_head; pX; pX = pX->m_next) {
237  A[i++] = pX;
238  }
239 
240  A.permute(1, m_size, rng);
241 
242  for (i = 1; i <= m_size; i++) {
243  pX = A[i];
244  pX->m_next = A[i + 1];
245  pX->m_prev = A[i - 1];
246  }
247 
248  m_head = A[1];
249  m_tail = A[m_size];
250 
251 #ifdef OGDF_DEBUG
252  consistencyCheck();
253 #endif
254  }
255 
257  void permute() {
258  std::minstd_rand rng(randomSeed());
259  permute(rng);
260  }
261 
262 #ifdef OGDF_DEBUG
263  void consistencyCheck() const {
265  OGDF_ASSERT((m_head == nullptr) == (m_tail == nullptr));
266 
267  if (m_head != nullptr) {
268  OGDF_ASSERT(m_head->m_prev == nullptr);
269  OGDF_ASSERT(m_tail->m_next == nullptr);
270 
271  for (GraphElement* pX = m_head; pX; pX = pX->m_next) {
272  if (pX->m_prev) {
273  OGDF_ASSERT(pX->m_prev->m_next == pX);
274  } else {
275  OGDF_ASSERT(pX == m_head);
276  }
277 
278  if (pX->m_next) {
279  OGDF_ASSERT(pX->m_next->m_prev == pX);
280  } else {
281  OGDF_ASSERT(pX == m_tail);
282  }
283  }
284  }
285  }
286 #endif
287 
289 };
290 
292 
295 template<class T>
296 class GraphList : protected GraphListBase {
297 public:
299  using value_type = T*;
304 
306  GraphList() { }
307 
310  if (m_head) {
311  OGDF_ALLOCATOR::deallocateList(sizeof(T), m_head, m_tail);
312  }
313  }
314 
315  using GraphListBase::empty;
316  using GraphListBase::size;
317 
319  T* head() const { return static_cast<T*>(m_head); }
320 
322  T* tail() const { return static_cast<T*>(m_tail); }
323 
325  void pushBack(T* pX) { GraphListBase::pushBack(pX); }
326 
328  void insertAfter(T* pX, T* pY) { GraphListBase::insertAfter(pX, pY); }
329 
331  void insertBefore(T* pX, T* pY) { GraphListBase::insertBefore(pX, pY); }
332 
334  void move(T* pX, GraphList<T>& L, T* pY, Direction dir) {
335  GraphListBase::del(pX);
336  if (dir == Direction::after) {
337  L.insertAfter(pX, pY);
338  } else {
339  L.insertBefore(pX, pY);
340  }
341  }
342 
344  void move(T* pX, GraphList<T>& L) {
345  GraphListBase::del(pX);
346  L.pushBack(pX);
347  }
348 
350  void moveAfter(T* pX, T* pY) {
351  GraphListBase::del(pX);
352  insertAfter(pX, pY);
353  }
354 
356  void moveBefore(T* pX, T* pY) {
357  GraphListBase::del(pX);
358  insertBefore(pX, pY);
359  }
360 
362  void del(T* pX) {
363  GraphListBase::del(pX);
364  delete pX;
365  }
366 
368  void delPure(T* pX) { GraphListBase::del(pX); }
369 
371  void clear() {
372  if (m_head) {
373  OGDF_ALLOCATOR::deallocateList(sizeof(T), m_head, m_tail);
374  m_head = m_tail = nullptr;
375  m_size = 0;
376  }
377  }
378 
380  iterator begin() const { return GraphList<T>::head(); }
381 
383  iterator end() const { return iterator(); }
384 
387 
389  reverse_iterator rend() const { return reverse_iterator(); }
390 
393  using GraphListBase::sort;
394 
396  void swap(T* pX, T* pY) { GraphListBase::swap(pX, pY); }
397 
398 #ifdef OGDF_DEBUG
400 #endif
401 };
402 
404 template<class GraphObject>
405 class GraphObjectContainer : private GraphList<GraphObject> {
406  friend class ogdf::Graph;
407  friend class ogdf::ClusterGraph;
410 
411 public:
412  using typename GraphList<GraphObject>::value_type;
413  using typename GraphList<GraphObject>::iterator;
415 
420 
425 };
426 
427 }
428 }
ogdf
The namespace for all OGDF objects.
Definition: AugmentationModule.h:36
ogdf::internal::GraphList::del
void del(T *pX)
Removes element pX from the list and deletes it.
Definition: GraphList.h:362
ogdf::Direction
Direction
Definition: basic.h:148
ogdf::internal::GraphListBase::insertAfter
void insertAfter(GraphElement *pX, GraphElement *pY)
Inserts element pX after element pY.
Definition: GraphList.h:102
ogdf::internal::GraphListBase::m_head
GraphElement * m_head
Pointer to the first element in the list.
Definition: GraphList.h:70
ogdf::internal::GraphList::moveAfter
void moveAfter(T *pX, T *pY)
Moves element pX from its current position to a position after pY.
Definition: GraphList.h:350
ogdf::internal::GraphListBase::del
void del(GraphElement *pX)
Removes element pX from the list.
Definition: GraphList.h:128
ogdf::internal::GraphList::tail
T * tail() const
Returns the last element in the list.
Definition: GraphList.h:322
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:54
ogdf::internal::GraphListBase::consistencyCheck
void consistencyCheck() const
Asserts consistency of this list.
Definition: GraphList.h:264
ogdf::internal::GraphIteratorBase
Definition: graph_iterators.h:44
ogdf::internal::GraphListBase::sort
void sort(const LIST &newOrder)
Sorts the list according to newOrder.
Definition: GraphList.h:146
ogdf::internal::GraphList::~GraphList
~GraphList()
Destruction: deletes all elements.
Definition: GraphList.h:309
ogdf::begin
HypergraphRegistry< HypernodeElement >::iterator begin(const HypergraphRegistry< HypernodeElement > &self)
ogdf::internal::GraphElement::m_next
GraphElement * m_next
The successor in the list.
Definition: GraphList.h:60
ogdf::internal::GraphElement
The base class for objects used by (hyper)graphs.
Definition: GraphList.h:55
ogdf::whaType::A
@ A
ogdf::internal::GraphListBase::GraphListBase
GraphListBase()
Constructs an empty list.
Definition: GraphList.h:75
ogdf::internal::GraphListBase::swap
void swap(GraphElement *pX, GraphElement *pY)
Exchanges the positions of pX and pY in the list.
Definition: GraphList.h:183
ogdf::internal::GraphListBase::permute
void permute()
Permutes all list elements.
Definition: GraphList.h:257
ogdf::internal::GraphObjectContainer
Public read-only interface for lists of graph objects.
Definition: GraphList.h:405
ogdf::internal::GraphList::delPure
void delPure(T *pX)
Only removes element pX from the list; does not delete it.
Definition: GraphList.h:368
ogdf::internal::GraphList::GraphList
GraphList()
Constructs an empty list.
Definition: GraphList.h:306
ogdf::internal::GraphList::rbegin
reverse_iterator rbegin() const
Returns a reverse iterator to the last element in the container.
Definition: GraphList.h:386
OGDF_NEW_DELETE
#define OGDF_NEW_DELETE
Makes the class use OGDF's memory allocator.
Definition: memory.h:84
ogdf::internal::GraphList::moveBefore
void moveBefore(T *pX, T *pY)
Moves element pX from its current position to a position before pY.
Definition: GraphList.h:356
ogdf::internal::GraphList::move
void move(T *pX, GraphList< T > &L, T *pY, Direction dir)
Moves element pX to list L and inserts it before or after pY.
Definition: GraphList.h:334
ogdf::internal::GraphListBase::size
int size() const
Returns the size of the list.
Definition: GraphList.h:84
ogdf::reverse
Reverse< T > reverse(T &container)
Provides iterators for container to make it easily iterable in reverse.
Definition: Reverse.h:74
ogdf::internal::GraphListBase::pushBack
void pushBack(GraphElement *pX)
Adds element pX at the end of the list.
Definition: GraphList.h:90
ogdf::internal::GraphListBase::m_tail
GraphElement * m_tail
Pointer to the last element in the list.
Definition: GraphList.h:71
ogdf::internal::GraphListBase::reverse
void reverse()
Reverses the order of the list elements.
Definition: GraphList.h:171
Minisat::Internal::sort
void sort(T *array, int size, LessThan lt)
Definition: Sort.h:57
ogdf::Direction::after
@ after
ogdf::internal::GraphListBase::insertBefore
void insertBefore(GraphElement *pX, GraphElement *pY)
Inserts element pX before element pY.
Definition: GraphList.h:115
ogdf::gml::Key::Graph
@ Graph
ogdf::Array
The parameterized class Array implements dynamic arrays of type E.
Definition: Array.h:214
ogdf::internal::GraphList::pushBack
void pushBack(T *pX)
Adds element pX at the end of the list.
Definition: GraphList.h:325
ogdf::internal::GraphList::insertBefore
void insertBefore(T *pX, T *pY)
Inserts element pX before element pY.
Definition: GraphList.h:331
ogdf::internal::GraphListBase
Base class for GraphElement lists.
Definition: GraphList.h:67
ogdf::Graph
Data type for general directed graphs (adjacency list representation).
Definition: Graph_d.h:862
ogdf::internal::GraphList
Lists of graph objects (like nodes, edges, etc.).
Definition: GraphList.h:296
ogdf::internal::GraphList::move
void move(T *pX, GraphList< T > &L)
Moves element pX to list L and inserts it at the end.
Definition: GraphList.h:344
ogdf::internal::GraphListBase::m_size
int m_size
The size of the list.
Definition: GraphList.h:69
ogdf::internal::GraphList::reverse_iterator
GraphReverseIterator< T * > reverse_iterator
Provides a bidirectional reverse iterator to an object in the container.
Definition: GraphList.h:303
graph_iterators.h
Decralation of graph iterators.
ogdf::internal::GraphList::rend
reverse_iterator rend() const
Returns a reverse iterator to the one-before-first element in the container.
Definition: GraphList.h:389
ogdf::randomSeed
long unsigned int randomSeed()
Returns a random value suitable as initial seed for a random number engine.
ogdf::internal::GraphList::iterator
GraphIterator< T * > iterator
Provides a bidirectional iterator to an object in the container.
Definition: GraphList.h:301
ogdf::ConstCombinatorialEmbedding
Combinatorial embeddings of planar graphs.
Definition: CombinatorialEmbedding.h:207
ogdf::internal::GraphList::begin
iterator begin() const
Returns an iterator to the first element in the container.
Definition: GraphList.h:380
ogdf::internal::GraphList::head
T * head() const
Returns the first element in the list.
Definition: GraphList.h:319
ogdf::internal::GraphElement::m_prev
GraphElement * m_prev
The predecessor in the list.
Definition: GraphList.h:61
ogdf::end
HypergraphRegistry< HypernodeElement >::iterator end(const HypergraphRegistry< HypernodeElement > &self)
OGDF_EXPORT
#define OGDF_EXPORT
Specifies that a function or class is exported by the OGDF DLL.
Definition: config.h:101
ogdf::internal::GraphList::end
iterator end() const
Returns an iterator to the one-past-last element in the container.
Definition: GraphList.h:383
ogdf::CombinatorialEmbedding
Combinatorial embeddings of planar graphs with modification functionality.
Definition: CombinatorialEmbedding.h:397
Array.h
Declaration and implementation of Array class and Array algorithms.
List.h
Declaration of doubly linked lists and iterators.
ogdf::internal::GraphList::clear
void clear()
Removes all elements from the list and deletes them.
Definition: GraphList.h:371
ogdf::internal::GraphListBase::empty
bool empty() const
Returns true iff the list is empty.
Definition: GraphList.h:87
ogdf::internal::GraphList::insertAfter
void insertAfter(T *pX, T *pY)
Inserts element pX after element pY.
Definition: GraphList.h:328
ogdf::internal::GraphListBase::~GraphListBase
~GraphListBase()
Destruction.
Definition: GraphList.h:81
ogdf::ClusterGraph
Representation of clustered graphs.
Definition: ClusterGraph.h:339
ogdf::internal::GraphList::swap
void swap(T *pX, T *pY)
Exchanges the positions of pX and pY in the list.
Definition: GraphList.h:396
ogdf::HypernodeElement
Class for the representation of hypernodes.
Definition: Hypergraph.h:217