Open
Graph Drawing
Framework

 v.2012.07
 

SList.h
Go to the documentation of this file.
1 /*
2  * $Revision: 2615 $
3  *
4  * last checkin:
5  * $Author: gutwenger $
6  * $Date: 2012-07-16 14:23:36 +0200 (Mo, 16. Jul 2012) $
7  ***************************************************************/
8 
46 #ifdef _MSC_VER
47 #pragma once
48 #endif
49 
50 #ifndef OGDF_SLIST_H
51 #define OGDF_SLIST_H
52 
53 
55 
56 
57 namespace ogdf {
58 
59 
60 template<class E> class SListPure;
61 template<class E> class StackPure;
62 template<class E> class SListIterator;
63 template<class E> class SListConstIterator;
64 
65 
67 template<class E>
68 class SListElement {
69  friend class SListPure<E>;
70  friend class StackPure<E>;
71  friend class SListIterator<E>;
72  friend class SListConstIterator<E>;
73 
75  E m_x;
76 
78  SListElement() : m_next(0) { }
80  SListElement(const E &x) : m_next(0), m_x(x) { }
82  SListElement(const E &x, SListElement<E> *next) :
83  m_next(next), m_x(x) { }
84 
86 }; // class SListElement
87 
88 
89 
91 
97 template<class E> class SListIterator {
99 
100  friend class SListConstIterator<E>;
101  friend class SListPure<E>;
102 
104  operator SListElement<E> *() { return m_pX; }
106  operator const SListElement<E> *() const { return m_pX; }
107 
108 public:
110  SListIterator() : m_pX(0) { }
115 
117  bool valid() const { return m_pX != 0; }
118 
120  bool operator==(const SListIterator<E> &it) const {
121  return m_pX == it.m_pX;
122  }
123 
125  bool operator!=(const SListIterator<E> &it) const {
126  return m_pX != it.m_pX;
127  }
128 
130  SListIterator<E> succ() const { return m_pX->m_next; }
131 
133  E &operator*() const { return m_pX->m_x; }
134 
137  m_pX = it.m_pX;
138  return *this;
139  }
140 
143  m_pX = m_pX->m_next;
144  return *this;
145  }
146 
149  SListIterator<E> it = *this;
150  m_pX = m_pX->m_next;
151  return it;
152  }
153 
155 }; // class SListIterator
156 
157 
158 
160 
167 template<class E> class SListConstIterator {
169 
170  friend class SListPure<E>;
171 
173  operator const SListElement<E> *() { return m_pX; }
174 
175 public:
178 
181 
183  SListConstIterator(const SListIterator<E> &it) : m_pX((const SListElement<E> *)it) { }
186 
188  bool valid() const { return m_pX != 0; }
189 
191  bool operator==(const SListConstIterator<E> &it) const {
192  return m_pX == it.m_pX;
193  }
194 
196  bool operator!=(const SListConstIterator<E> &it) const {
197  return m_pX != it.m_pX;
198  }
199 
201  SListConstIterator<E> succ() const { return m_pX->m_next; }
202 
204  const E &operator*() const { return m_pX->m_x; }
205 
208  m_pX = it.m_pX;
209  return *this;
210  }
211 
212 
215  m_pX = m_pX->m_next;
216  return *this;
217  }
218 
221  SListConstIterator<E> it = *this;
222  m_pX = m_pX->m_next;
223  return it;
224  }
225 
227 }; // class SListConstIterator
228 
229 
231 
240 template<class E> class SListPure {
243 
244 public:
246  SListPure() : m_head(0), m_tail(0) { }
247 
249  SListPure(const SListPure<E> &L) : m_head(0), m_tail(0) {
250  copy(L);
251  }
252 
253  // destruction
254  ~SListPure() { clear(); }
255 
256  typedef E value_type;
260 
262  bool empty() const { return m_head == 0; }
263 
265 
268  int size() const {
269  int count = 0;
270  for (SListElement<E> *pX = m_head; pX; pX = pX->m_next)
271  ++count;
272  return count;
273  }
274 
276 
279  SListConstIterator<E> begin() const { return m_head; }
280 
282 
286 
288 
292 
294 
298 
300 
303  SListConstIterator<E> rbegin() const { return m_tail; }
304 
306 
310 
311 
313 
316  SListConstIterator<E> get(int pos) const {
317  SListElement<E> *pX;
318  for(pX = m_head; pX != 0; pX = pX->m_next)
319  if (pos-- == 0) break;
320  return pX;
321  }
322 
324 
328  SListElement<E> *pX;
329  for(pX = m_head; pX != 0; pX = pX->m_next)
330  if (pos-- == 0) break;
331  return pX;
332  }
333 
335 
339  int pos(SListConstIterator<E> it) const {
340  OGDF_ASSERT(it.valid())
341  int p = 0;
342  for(SListElement<E> *pX = m_head; pX != 0; pX = pX->m_next, ++p)
343  if (pX == it) break;
344  return p;
345  }
346 
347 
349 
352  const E &front() const {
353  OGDF_ASSERT(m_head != 0)
354  return m_head->m_x;
355  }
356 
358 
361  E &front() {
362  OGDF_ASSERT(m_head != 0)
363  return m_head->m_x;
364  }
365 
367 
370  const E &back() const {
371  OGDF_ASSERT(m_tail != 0)
372  return m_tail->m_x;
373  }
374 
376 
379  E &back() {
380  OGDF_ASSERT(m_tail != 0)
381  return m_tail->m_x;
382  }
383 
385 
389  const SListElement<E> *pX = it;
390  return (pX->m_next) ? pX->m_next : m_head;
391  }
392 
394 
398  SListElement<E> *pX = it;
399  return (pX->m_next) ? pX->m_next : m_head;
400  }
401 
404  clear(); copy(L);
405  return *this;
406  }
407 
411  if (m_tail == 0) m_tail = m_head;
412  return m_head;
413  }
414 
418  if (m_head == 0)
419  m_head = m_tail = pNew;
420  else
421  m_tail = m_tail->m_next = pNew;
422  return m_tail;
423  }
424 
426 
430  SListElement<E> *pBefore = itBefore;
431  OGDF_ASSERT(pBefore != 0)
432  SListElement<E> *pNew = OGDF_NEW SListElement<E>(x,pBefore->m_next);
433  if (pBefore == m_tail) m_tail = pNew;
434  return (pBefore->m_next = pNew);
435  }
436 
438 
441  void popFront() {
442  OGDF_ASSERT(m_head != 0)
443  SListElement<E> *pX = m_head;
444  if ((m_head = m_head->m_next) == 0) m_tail = 0;
445  delete pX;
446  }
447 
449 
453  E el = front();
454  popFront();
455  return el;
456  }
457 
459 
462  void delSucc(SListIterator<E> itBefore) {
463  SListElement<E> *pBefore = itBefore;
464  OGDF_ASSERT(pBefore != 0)
465  SListElement<E> *pDel = pBefore->m_next;
466  OGDF_ASSERT(pDel != 0)
467  if ((pBefore->m_next = pDel->m_next) == 0) m_tail = pBefore;
468  delete pDel;
469  }
470 
473  OGDF_ASSERT(m_head != 0)
474  OGDF_ASSERT(this != &L2)
475  SListElement<E> *pX = m_head;
476  if ((m_head = m_head->m_next) == 0) m_tail = 0;
477  pX->m_next = L2.m_head;
478  L2.m_head = pX;
479  if (L2.m_tail == 0) L2.m_tail = L2.m_head;
480  }
481 
484  OGDF_ASSERT(m_head != 0)
485  OGDF_ASSERT(this != &L2)
486  SListElement<E> *pX = m_head;
487  if ((m_head = m_head->m_next) == 0) m_tail = 0;
488  pX->m_next = 0;
489  if (L2.m_head == 0)
490  L2.m_head = L2.m_tail = pX;
491  else
492  L2.m_tail = L2.m_tail->m_next = pX;
493  }
494 
496 
500  OGDF_ASSERT(m_head != 0)
501  OGDF_ASSERT(this != &L2)
502  SListElement<E> *pBefore = itBefore;
503  SListElement<E> *pX = m_head;
504  if ((m_head = m_head->m_next) == 0) m_tail = 0;
505  pX->m_next = pBefore->m_next;
506  pBefore->m_next = pX;
507  if (pBefore == L2.m_tail) L2.m_tail = pX;
508  }
509 
511  void clear() {
512  if (m_head == 0) return;
513 
514 #if (_MSC_VER == 1100)
515 // workaround for bug in Visual Studio 5.0
516 
517  while (!empty())
518  popFront();
519 
520 #else
521 
522  if (doDestruction((E*)0)) {
523  for(SListElement<E> *pX = m_head; pX != 0; pX = pX->m_next)
524  pX->m_x.~E();
525  }
526  OGDF_ALLOCATOR::deallocateList(sizeof(SListElement<E>),m_head,m_tail);
527 
528 #endif
529 
530  m_head = m_tail = 0;
531  }
532 
534  void conc(SListPure<E> &L2) {
535  if (m_head)
536  m_tail->m_next = L2.m_head;
537  else
538  m_head = L2.m_head;
539  if (L2.m_tail != 0) m_tail = L2.m_tail;
540  L2.m_head = L2.m_tail = 0;
541  }
542 
544  void reverse() {
545  SListElement<E> *p, *pNext, *pPred = 0;
546  for(p = m_head; p; p = pNext) {
547  pNext = p->m_next;
548  p->m_next = pPred;
549  pPred = p;
550  }
551  swap(m_head,m_tail);
552  }
553 
555  const SListPure<E> &getListPure() const { return *this; }
556 
558  void quicksort() {
560  }
561 
563  template<class COMPARER>
564  void quicksort(const COMPARER &comp) {
565  ogdf::quicksortTemplate(*this,comp);
566  }
567 
569 
576  void bucketSort(int l, int h, BucketFunc<E> &f);
577 
579  void bucketSort(BucketFunc<E> &f);
580 
582  void permute() {
583  permute(size());
584  }
585 
587  int search (const E& e) const {
588  int x = 0;
589  for(SListConstIterator<E> i = begin(); i.valid(); ++i, ++x)
590  if(*i == e) return x;
591  return -1;
592  }
593 
595  template<class COMPARER>
596  int search (const E& e, const COMPARER &comp) const {
597  int x = 0;
598  for(SListConstIterator<E> i = begin(); i.valid(); ++i, ++x)
599  if(comp.equal(*i,e)) return x;
600  return -1;
601  }
602 
603 protected:
604  void copy(const SListPure<E> &L) {
605  for(SListElement<E> *pX = L.m_head; pX != 0; pX = pX->m_next)
606  pushBack(pX->m_x);
607  }
608 
609  void permute(const int n);
610 
612 }; // class SListPure
613 
614 
615 
617 
626 template<class E>
627 class SList : private SListPure<E> {
628 
629  int m_count;
630 
631 public:
633  SList() : m_count(0) { }
634 
636  SList(const SList<E> &L) : SListPure<E>(L), m_count(L.m_count) { }
637 
638  // destruction
639  ~SList() { }
640 
641  typedef E value_type;
645 
647  bool empty() const { return SListPure<E>::empty(); }
648 
650  int size() const { return m_count; }
651 
653 
656  const SListConstIterator<E> begin() const { return SListPure<E>::begin(); }
657 
659 
663 
665 
669 
671 
675 
677 
681 
683 
687 
688 
690 
693  SListConstIterator<E> get(int pos) const {
694  return SListPure<E>::get(pos);
695  }
696 
698 
702  return SListPure<E>::get(pos);
703  }
704 
706 
710  int pos(SListConstIterator<E> it) const {
711  return SListPure<E>::pos(it);;
712  }
713 
714 
716 
719  const E &front() const { return SListPure<E>::front(); }
720 
722 
725  E &front() { return SListPure<E>::front(); }
726 
728 
731  const E &back() const { return SListPure<E>::back(); }
732 
734 
737  E &back() { return SListPure<E>::back(); }
738 
740 
744  return SListPure<E>::cyclicSucc(it);
745  }
746 
748 
752  return SListPure<E>::cyclicSucc(it);
753  }
754 
758  m_count = L.m_count;
759  return *this;
760  }
761 
764  ++m_count;
765  return SListPure<E>::pushFront(x);
766  }
767 
770  ++m_count;
771  return SListPure<E>::pushBack(x);
772  }
773 
775 
779  ++m_count;
780  return SListPure<E>::insertAfter(x, itBefore);
781  }
782 
784 
787  void popFront() {
788  --m_count;
790  }
791 
793 
797  E el = front();
798  popFront();
799  return el;
800  }
801 
803 
806  void delSucc(SListIterator<E> itBefore) {
807  --m_count;
808  SListPure<E>::delSucc(itBefore);
809  }
810 
814  --m_count; ++L2.m_count;
815  }
816 
820  --m_count; ++L2.m_count;
821  }
822 
824 
828  SListPure<E>::moveFrontToSucc(L2,itBefore);
829  --m_count; ++L2.m_count;
830  }
831 
833  void clear() {
834  m_count = 0;
836  }
837 
839  void conc(SList<E> &L2) {
840  SListPure<E>::conc(L2);
841  m_count += L2.m_count;
842  L2.m_count = 0;
843  }
844 
846  void reverse() {
848  }
849 
851  const SListPure<E> &getListPure() const { return *this; }
852 
854  void quicksort() {
856  }
857 
859  template<class COMPARER>
860  void quicksort(const COMPARER &comp) {
861  ogdf::quicksortTemplate(*this,comp);
862  }
863 
865 
872  void bucketSort(int l, int h, BucketFunc<E> &f) {
874  }
875 
879  }
880 
882  void permute() {
884  }
885 
887  int search (const E& e) const {
888  return SListPure<E>::search(e);
889  }
890 
892  template<class COMPARER>
893  int search (const E& e, const COMPARER &comp) const {
894  return SListPure<E>::search(e, comp);
895  }
896 
898 }; // class SList
899 
900 
901 
902 
903 // sorts list L using bucket sort
904 // computes l and h value
905 template<class E>
907 {
908  // if less than two elements, nothing to do
909  if (m_head == m_tail) return;
910 
911  int l, h;
912  l = h = f.getBucket(m_head->m_x);
913 
914  SListElement<E> *pX;
915  for(pX = m_head->m_next; pX; pX = pX->m_next)
916  {
917  int i = f.getBucket(pX->m_x);
918  if (i < l) l = i;
919  if (i > h) h = i;
920  }
921 
922  bucketSort(l,h,f);
923 }
924 
925 
926 // sorts list L using bucket sort
927 template<class E>
929 {
930  // if less than two elements, nothing to do
931  if (m_head == m_tail) return;
932 
933  Array<SListElement<E> *> head(l,h,0), tail(l,h);
934 
935  SListElement<E> *pX;
936  for (pX = m_head; pX; pX = pX->m_next) {
937  int i = f.getBucket(pX->m_x);
938  if (head[i])
939  tail[i] = (tail[i]->m_next = pX);
940  else
941  head[i] = tail[i] = pX;
942  }
943 
944  SListElement<E> *pY = 0;
945  for (int i = l; i <= h; i++) {
946  pX = head[i];
947  if (pX) {
948  if (pY)
949  pY->m_next = pX;
950  else
951  m_head = pX;
952  pY = tail[i];
953  }
954  }
955 
956  m_tail = pY;
957  pY->m_next = 0;
958 }
959 
960 
961 // permutes elements in list randomly; n is the length of the list
962 template<class E>
963 void SListPure<E>::permute(const int n)
964 {
965  Array<SListElement<E> *> A(n+1);
966  A[n] = 0;
967 
968  int i = 0;
969  SListElement<E> *pX;
970  for (pX = m_head; pX; pX = pX->m_next)
971  A[i++] = pX;
972 
973  A.permute(0,n-1);
974 
975  for (i = 0; i < n; i++) {
976  A[i]->m_next = A[i+1];
977  }
978 
979  m_head = A[0];
980  m_tail = A[n-1];
981 }
982 
983 // prints list to output stream os using delimiter delim
984 template<class E>
985 void print(ostream &os, const SListPure<E> &L, char delim = ' ')
986 {
987  SListConstIterator<E> pX = L.begin();
988  if (pX.valid()) {
989  os << *pX;
990  for(++pX; pX.valid(); ++pX)
991  os << delim << *pX;
992  }
993 }
994 
995 // prints list to output stream os using delimiter delim
996 template<class E>
997 void print(ostream &os, const SList<E> &L, char delim = ' ')
998 {
999  print(L.getListPure(), delim);
1000 }
1001 
1002 // output operator
1003 template<class E>
1004 ostream &operator<<(ostream &os, const SListPure<E> &L)
1005 {
1006  print(os,L);
1007  return os;
1008 }
1009 
1010 template<class E>
1011 ostream &operator<<(ostream &os, const SList<E> &L)
1012 {
1013  return operator<<(os,L.getListPure());
1014 }
1015 
1016 
1017 // sort array using bucket sort and bucket object f;
1018 // the values of f must be in the interval [min,max]
1019 template<class E>
1020 void bucketSort(Array<E> &a, int min, int max, BucketFunc<E> &f)
1021 {
1022  if (a.low() >= a.high()) return;
1023 
1024  Array<SListPure<E> > bucket(min,max);
1025 
1026  int i;
1027  for(i = a.low(); i <= a.high(); ++i)
1028  bucket[f.getBucket(a[i])].pushBack(a[i]);
1029 
1030  i = a.low();
1031  for(int j = min; j <= max; ++j) {
1032  SListConstIterator<E> it = bucket[j].begin();
1033  for(; it.valid(); ++it)
1034  a[i++] = *it;
1035  }
1036 }
1037 
1038 
1039 
1040 
1041 } // namespace ogdf
1042 
1043 
1044 #endif