Open
Graph Drawing
Framework

 v.2012.07
 

List.h
Go to the documentation of this file.
1 /*
2  * $Revision: 2632 $
3  *
4  * last checkin:
5  * $Author: gutwenger $
6  * $Date: 2012-07-17 21:04:24 +0200 (Di, 17. Jul 2012) $
7  ***************************************************************/
8 
43 #ifdef _MSC_VER
44 #pragma once
45 #endif
46 
47 #ifndef OGDF_LIST_H
48 #define OGDF_LIST_H
49 
50 
52 
53 
54 namespace ogdf {
55 
56 
57 template<class E> class List;
58 template<class E> class ListPure;
59 template<class E> class ListIterator;
60 template<class E> class ListConstIterator;
61 
62 
64 template<class E>
65 class ListElement {
66  friend class ListPure<E>;
67  friend class List<E>;
68  friend class ListIterator<E>;
69  friend class ListConstIterator<E>;
70 
73  E m_x;
74 
76  ListElement() : m_next(0), m_prev(0) { }
78  ListElement(const E &x) : m_next(0), m_prev(0), m_x(x) { }
80  ListElement(const E &x, ListElement<E> *next, ListElement<E> *prev) :
81  m_next(next), m_prev(prev), m_x(x) { }
82 
84 }; // class ListElement
85 
86 
87 
89 
95 template<class E> class ListIterator {
96  ListElement<E> *m_pX; // pointer to associated list element
97 
98  friend class ListConstIterator<E>;
99  friend class ListPure<E>;
100 
102  operator ListElement<E> *() { return m_pX; }
104  operator const ListElement<E> *() const { return m_pX; }
105 
106 public:
108  ListIterator() : m_pX(0) { }
112  ListIterator(const ListIterator<E> &it) : m_pX(it.m_pX) { }
113 
115  bool valid() const { return m_pX != 0; }
116 
118  bool operator==(const ListIterator<E> &it) const {
119  return m_pX == it.m_pX;
120  }
121 
123  bool operator!=(const ListIterator<E> &it) const {
124  return m_pX != it.m_pX;
125  }
126 
128  ListIterator<E> succ() const { return m_pX->m_next; }
129 
131  ListIterator<E> pred() const { return m_pX->m_prev; }
132 
134  E &operator*() const { return m_pX->m_x; }
135 
138  m_pX = it.m_pX;
139  return *this;
140  }
141 
144  m_pX = m_pX->m_next;
145  return *this;
146  }
147 
150  ListIterator<E> it = *this;
151  m_pX = m_pX->m_next;
152  return it;
153  }
154 
157  m_pX = m_pX->m_prev;
158  return *this;
159  }
160 
163  ListIterator<E> it = *this;
164  m_pX = m_pX->m_prev;
165  return it;
166  }
167 
169 }; // class ListIterator
170 
171 
172 
173 //---------------------------------------------------------
174 // ListConstIterator<E>
175 // const iterator for doubly linked lists
176 //---------------------------------------------------------
178 
185 template<class E> class ListConstIterator {
186  const ListElement<E> *m_pX; // pointer to list element
187 
188  friend class ListPure<E>;
189 
191  operator const ListElement<E> *() { return m_pX; }
192 
193 public:
196 
198  ListConstIterator(const ListElement<E> *pX) : m_pX(pX) { }
199 
201  ListConstIterator(const ListIterator<E> &it) : m_pX((const ListElement<E> *)it) { }
204 
206  bool valid() const { return m_pX != 0; }
207 
209  bool operator==(const ListConstIterator<E> &it) const {
210  return m_pX == it.m_pX;
211  }
212 
214  bool operator!=(const ListConstIterator<E> &it) const {
215  return m_pX != it.m_pX;
216  }
217 
219  ListConstIterator<E> succ() const { return m_pX->m_next; }
220 
222  ListConstIterator<E> pred() const { return m_pX->m_prev; }
223 
225  const E &operator*() const { return m_pX->m_x; }
226 
229  m_pX = it.m_pX;
230  return *this;
231  }
232 
235  m_pX = m_pX->m_next;
236  return *this;
237  }
238 
241  ListConstIterator<E> it = *this;
242  m_pX = m_pX->m_next;
243  return it;
244  }
245 
248  m_pX = m_pX->m_prev;
249  return *this;
250  }
251 
254  ListConstIterator<E> it = *this;
255  m_pX = m_pX->m_prev;
256  return it;
257  }
258 
260 }; // class ListConstIterator
261 
262 
263 
265 
274 template<class E> class ListPure {
275 protected:
276 
279 
280 public:
282  ListPure() : m_head(0), m_tail(0) { }
283 
285  ListPure(const ListPure<E> &L) : m_head(0), m_tail(0) {
286  copy(L);
287  }
288 
289  // destruction
290  ~ListPure() { clear(); }
291 
292  typedef E value_type;
296 
298  bool empty() const { return m_head == 0; }
299 
301 
304  int size() const {
305  int count = 0;
306  for (ListElement<E> *pX = m_head; pX; pX = pX->m_next)
307  ++count;
308  return count;
309  }
310 
312 
315  const ListConstIterator<E> begin() const { return m_head; }
317 
321 
323 
328 
332 
334 
337  const ListConstIterator<E> rbegin() const { return m_tail; }
339 
343 
345 
350 
354 
356 
359  const E &front() const {
360  OGDF_ASSERT(m_head != 0)
361  return m_head->m_x;
362  }
363 
365 
368  E &front() {
369  OGDF_ASSERT(m_head != 0)
370  return m_head->m_x;
371  }
372 
374 
377  const E &back() const {
378  OGDF_ASSERT(m_tail != 0)
379  return m_tail->m_x;
380  }
381 
383 
386  E &back() {
387  OGDF_ASSERT(m_tail != 0)
388  return m_tail->m_x;
389  }
390 
392 
396  const ListElement<E> *pX = it;
397  return (pX->m_next) ? pX->m_next : m_head;
398  }
399 
401 
405  OGDF_ASSERT(it.valid())
406  ListElement<E> *pX = it;
407  return (pX->m_next) ? pX->m_next : m_head;
408  }
409 
411 
415  OGDF_ASSERT(it.valid())
416  const ListElement<E> *pX = it;
417  return (pX->m_prev) ? pX->m_prev : m_tail;
418  }
419 
421 
425  OGDF_ASSERT(it.valid())
426  ListElement<E> *pX = it;
427  return (pX->m_prev) ? pX->m_prev : m_tail;
428  }
429 
431 
434  ListConstIterator<E> get(int pos) const {
435  ListElement<E> *pX;
436  for(pX = m_head; pX != 0; pX = pX->m_next)
437  if (pos-- == 0) break;
438  return pX;
439  }
440 
442 
445  ListIterator<E> get(int pos) {
446  ListElement<E> *pX;
447  for(pX = m_head; pX != 0; pX = pX->m_next)
448  if (pos-- == 0) break;
449  return pX;
450  }
451 
453 
456  int pos(ListConstIterator<E> it) const {
457  OGDF_ASSERT(it.valid())
458  int p = 0;
459  for(ListElement<E> *pX = m_head; pX != 0; pX = pX->m_next, ++p)
460  if (pX == it) break;
461  return p;
462  }
463 
465 
469  return empty() ? ListConstIterator<E>() : get(randomNumber(0,size()-1));
470  }
471 
473 
477  return empty() ? ListIterator<E>() : get(randomNumber(0,size()-1));
478  }
479 
481 
486  const E chooseElement() const {
487  OGDF_ASSERT(m_head != 0)
488  return *chooseIterator();
489  }
490 
492 
498  return *chooseIterator();
499  }
500 
503  clear(); copy(L);
504  return *this;
505  }
506 
508  bool operator==(const ListPure<E> &L) const {
509  ListElement<E> *pX = m_head, *pY = L.m_head;
510  while(pX != 0 && pY != 0) {
511  if(pX->m_x != pY->m_x)
512  return false;
513  pX = pX->m_next;
514  pY = pY->m_next;
515  }
516  return (pX == 0 && pY == 0);
517  }
518 
520  bool operator!=(const ListPure<E> &L) const {
521  return !operator==(L);
522  }
523 
527  if (m_head)
528  m_head = m_head->m_prev = pX;
529  else
530  m_head = m_tail = pX;
531  return m_head;
532  }
533 
535  ListIterator<E> pushBack(const E &x) {
537  if (m_head)
538  m_tail = m_tail->m_next = pX;
539  else
540  m_tail = m_head = pX;
541  return m_tail;
542  }
543 
545 
553  OGDF_ASSERT(it.valid())
554  OGDF_ASSERT(dir == after || dir == before)
555  ListElement<E> *pY = it, *pX;
556  if (dir == after) {
557  ListElement<E> *pYnext = pY->m_next;
558  pY->m_next = pX = OGDF_NEW ListElement<E>(x,pYnext,pY);
559  if (pYnext) pYnext->m_prev = pX;
560  else m_tail = pX;
561  } else {
562  ListElement<E> *pYprev = pY->m_prev;
563  pY->m_prev = pX = OGDF_NEW ListElement<E>(x,pY,pYprev);
564  if (pYprev) pYprev->m_next = pX;
565  else m_head = pX;
566  }
567  return pX;
568  }
569 
571 
575  OGDF_ASSERT(it.valid())
576  ListElement<E> *pY = it, *pX;
577  ListElement<E> *pYprev = pY->m_prev;
578  pY->m_prev = pX = OGDF_NEW ListElement<E>(x,pY,pYprev);
579  if (pYprev) pYprev->m_next = pX;
580  else m_head = pX;
581  return pX;
582  }
583 
585 
589  OGDF_ASSERT(it.valid())
590  ListElement<E> *pY = it, *pX;
591  ListElement<E> *pYnext = pY->m_next;
592  pY->m_next = pX = OGDF_NEW ListElement<E>(x,pYnext,pY);
593  if (pYnext) pYnext->m_prev = pX;
594  else m_tail = pX;
595  return pX;
596  }
597 
599 
602  void popFront() {
603  OGDF_ASSERT(m_head != 0)
604  ListElement<E> *pX = m_head;
605  m_head = m_head->m_next;
606  delete pX;
607  if (m_head) m_head->m_prev = 0;
608  else m_tail = 0;
609  }
610 
612 
616  E el = front();
617  popFront();
618  return el;
619  }
620 
622 
625  void popBack() {
626  OGDF_ASSERT(m_tail != 0)
627  ListElement<E> *pX = m_tail;
628  m_tail = m_tail->m_prev;
629  delete pX;
630  if (m_tail) m_tail->m_next = 0;
631  else m_head = 0;
632  }
633 
635 
639  E el = back();
640  popBack();
641  return el;
642  }
643 
645 
648  void del(ListIterator<E> it) {
649  OGDF_ASSERT(it.valid())
650  ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
651  delete pX;
652  if (pPrev) pPrev->m_next = pNext;
653  else m_head = pNext;
654  if (pNext) pNext->m_prev = pPrev;
655  else m_tail = pPrev;
656  }
657 
659 
663  OGDF_ASSERT(it1.valid() && it2.valid() && it1 != it2)
664  ListElement<E> *pX = it1, *pY = it2;
665 
666  std::swap(pX->m_next,pY->m_next);
667  std::swap(pX->m_prev,pY->m_prev);
668 
669  if(pX->m_next == pX) {
670  pX->m_next = pY; pY->m_prev = pX;
671  }
672  if(pX->m_prev == pX) {
673  pX->m_prev = pY; pY->m_next = pX;
674  }
675 
676  if(pX->m_prev) pX->m_prev->m_next = pX;
677  else m_head = pX;
678 
679  if(pY->m_prev) pY->m_prev->m_next = pY;
680  else m_head = pY;
681 
682  if(pX->m_next) pX->m_next->m_prev = pX;
683  else m_tail = pX;
684 
685  if(pY->m_next) pY->m_next->m_prev = pY;
686  else m_tail = pY;
687  }
688 
690 
694  OGDF_ASSERT(it.valid())
695  // remove it
696  ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
697  //already at front
698  if (!pPrev) return;
699 
700  //update old position
701  if (pPrev) pPrev->m_next = pNext;
702  if (pNext) pNext->m_prev = pPrev;
703  else m_tail = pPrev;
704  // insert it at front
705  pX->m_prev = 0;
706  pX->m_next = m_head;
707  m_head = m_head->m_prev = pX;
708  }//move
709 
711 
715  OGDF_ASSERT(it.valid())
716  // remove it
717  ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
718  //already at back
719  if (!pNext) return;
720 
721  //update old position
722  if (pPrev) pPrev->m_next = pNext;
723  else m_head = pNext;
724  if (pNext) pNext->m_prev = pPrev;
725  // insert it at back
726  pX->m_prev = m_tail;
727  pX->m_next = 0;
728  m_tail = m_tail->m_next = pX;
729  }//move
730 
732 
736  OGDF_ASSERT(it.valid() && itBefore.valid())
737  // move it
738  ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
739  //the same of already in place
740  ListElement<E> *pY = itBefore;
741  if(pX == pY || pPrev == pY) return;
742 
743  // update old position
744  if (pPrev) pPrev->m_next = pNext;
745  else m_head = pNext;
746  if (pNext) pNext->m_prev = pPrev;
747  else m_tail = pPrev;
748  // move it after itBefore
749  ListElement<E> *pYnext = pX->m_next = pY->m_next;
750  (pX->m_prev = pY)->m_next = pX;
751  if (pYnext) pYnext->m_prev = pX;
752  else m_tail = pX;
753  }//move
754 
756 
760  OGDF_ASSERT(it.valid() && itAfter.valid())
761  // move it
762  ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
763  //the same of already in place
764  ListElement<E> *pY = itAfter;
765  if(pX == pY || pNext == pY) return;
766 
767  // update old position
768  if (pPrev) pPrev->m_next = pNext;
769  else m_head = pNext;
770  if (pNext) pNext->m_prev = pPrev;
771  else m_tail = pPrev;
772  // move it before itAfter
773  ListElement<E> *pYprev = pX->m_prev = pY->m_prev;
774  (pX->m_next = pY)->m_prev = pX;
775  if (pYprev) pYprev->m_next = pX;
776  else m_head = pX;
777  }//move
778 
780 
784  OGDF_ASSERT(it.valid())
785  OGDF_ASSERT(this != &L2)
786  // remove it
787  ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
788  if (pPrev) pPrev->m_next = pNext;
789  else m_head = pNext;
790  if (pNext) pNext->m_prev = pPrev;
791  else m_tail = pPrev;
792  // insert it at front of L2
793  pX->m_prev = 0;
794  if ((pX->m_next = L2.m_head) != 0)
795  L2.m_head = L2.m_head->m_prev = pX;
796  else
797  L2.m_head = L2.m_tail = pX;
798  }
799 
801 
805  OGDF_ASSERT(it.valid())
806  OGDF_ASSERT(this != &L2)
807  // remove it
808  ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
809  if (pPrev) pPrev->m_next = pNext;
810  else m_head = pNext;
811  if (pNext) pNext->m_prev = pPrev;
812  else m_tail = pPrev;
813  // insert it at back of L2
814  pX->m_next = 0;
815  if ((pX->m_prev = L2.m_tail) != 0)
816  L2.m_tail = L2.m_tail->m_next = pX;
817  else
818  L2.m_head = L2.m_tail = pX;
819  }
820 
822 
827  OGDF_ASSERT(it.valid() && itBefore.valid())
828  OGDF_ASSERT(this != &L2)
829  // remove it
830  ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
831  if (pPrev) pPrev->m_next = pNext;
832  else m_head = pNext;
833  if (pNext) pNext->m_prev = pPrev;
834  else m_tail = pPrev;
835  // insert it in list L2 after itBefore
836  ListElement<E> *pY = itBefore;
837  ListElement<E> *pYnext = pX->m_next = pY->m_next;
838  (pX->m_prev = pY)->m_next = pX;
839  if (pYnext) pYnext->m_prev = pX;
840  else L2.m_tail = pX;
841  }
842 
844 
849  OGDF_ASSERT(it.valid() && itAfter.valid())
850  OGDF_ASSERT(this != &L2)
851  // remove it
852  ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
853  if (pPrev) pPrev->m_next = pNext;
854  else m_head = pNext;
855  if (pNext) pNext->m_prev = pPrev;
856  else m_tail = pPrev;
857  // insert it in list L2 after itBefore
858  ListElement<E> *pY = itAfter;
859  ListElement<E> *pYprev = pX->m_prev = pY->m_prev;
860  (pX->m_next = pY)->m_prev = pX;
861  if (pYprev) pYprev->m_next = pX;
862  else L2.m_head = pX;
863  }
864 
866  void conc(ListPure<E> &L2) {
867  OGDF_ASSERT(this != &L2)
868  if (m_head)
869  m_tail->m_next = L2.m_head;
870  else
871  m_head = L2.m_head;
872  if (L2.m_head) {
873  L2.m_head->m_prev = m_tail;
874  m_tail = L2.m_tail;
875  }
876  L2.m_head = L2.m_tail = 0;
877  }
878 
880  void concFront(ListPure<E> &L2) {
881  OGDF_ASSERT(this != &L2)
882  if (m_head)
883  m_head->m_prev = L2.m_tail;
884  else
885  m_tail = L2.m_tail;
886  if (L2.m_head) {
887  L2.m_tail->m_next = m_head;
888  m_head = L2.m_head;
889  }
890  L2.m_head = L2.m_tail = 0;
891  }
892 
894 
897  void exchange(ListPure<E>& L2) {
898  ListElement<E>* t;
899  t = this->m_head;
900  this->m_head = L2.m_head;
901  L2.m_head = t;
902  t = this->m_tail;
903  this->m_tail = L2.m_tail;
904  L2.m_tail = t;
905  }
906 
908 
918  if (&L1 != this) L1.clear();
919  if (&L2 != this) L2.clear();
920 
921  if (it.valid()){
922  L1.m_head = m_head;
923  L2.m_tail = m_tail;
924  if (dir == before){
925  L2.m_head = it;
926  L1.m_tail = L2.m_head->m_prev;
927  }
928  else {
929  L1.m_tail = it;
930  L2.m_head = L1.m_tail->m_next;
931  }
932  L2.m_head->m_prev = L1.m_tail->m_next = 0;
933 
934  } else {
935  L1.m_head = L1.m_tail = 0;
936  L2.m_head = m_head;
937  L2.m_tail = m_tail;
938  }
939 
940  if (this != &L1 && this != &L2) {
941  m_head = m_tail = 0;
942  }
943  }
944 
947  OGDF_ASSERT(it.valid())
948  OGDF_ASSERT(this != &L2)
949  L2.clear();
950  ListElement<E> *pX = it;
951  if (pX != m_tail) {
952  (L2.m_head = pX->m_next)->m_prev = 0;
953  pX->m_next = 0;
954  L2.m_tail = m_tail;
955  m_tail = pX;
956  }
957  }
958 
961  OGDF_ASSERT(it.valid())
962  OGDF_ASSERT(this != &L2)
963  L2.clear();
964  ListElement<E> *pX = it;
965  L2.m_head = pX; L2.m_tail = m_tail;
966  if ((m_tail = pX->m_prev) == 0)
967  m_head = 0;
968  else
969  m_tail->m_next = 0;
970  pX->m_prev = 0;
971  }
972 
974  void reverse() {
975  ListElement<E> *pX = m_head;
976  m_head = m_tail;
977  m_tail = pX;
978  while(pX) {
979  ListElement<E> *pY = pX->m_next;
980  pX->m_next = pX->m_prev;
981  pX = pX->m_prev = pY;
982  }
983  }
984 
986  void clear() {
987  if (m_head == 0) return;
988 
989 #if (_MSC_VER == 1100)
990 // workaround for bug in Visual Studio 5.0
991 
992  while (!empty())
993  popFront();
994 
995 #else
996 
997  if (doDestruction((E*)0)) {
998  for(ListElement<E> *pX = m_head; pX != 0; pX = pX->m_next)
999  pX->m_x.~E();
1000  }
1001  OGDF_ALLOCATOR::deallocateList(sizeof(ListElement<E>),m_head,m_tail);
1002 
1003 #endif
1004 
1005  m_head = m_tail = 0;
1006  }
1007 
1009  void quicksort() {
1010  ogdf::quicksortTemplate(*this);
1011  }
1012 
1014  template<class COMPARER>
1015  void quicksort(const COMPARER &comp) {
1016  ogdf::quicksortTemplate(*this,comp);
1017  }
1018 
1020 
1027  void bucketSort(int l, int h, BucketFunc<E> &f);
1028 
1030  void permute() {
1031  permute(size());
1032  }
1033 
1035  int search (const E& e) const {
1036  int x = 0;
1037  for(ListConstIterator<E> i = begin(); i.valid(); ++i, ++x)
1038  if(*i == e) return x;
1039  return -1;
1040  }
1041 
1043  template<class COMPARER>
1044  int search (const E& e, const COMPARER &comp) const {
1045  int x = 0;
1046  for(ListConstIterator<E> i = begin(); i.valid(); ++i, ++x)
1047  if(comp.equal(*i,e)) return x;
1048  return -1;
1049  }
1050 
1051 protected:
1052  void copy(const ListPure<E> &L) {
1053  for(ListElement<E> *pX = L.m_head; pX != 0; pX = pX->m_next)
1054  pushBack(pX->m_x);
1055  }
1056 
1057  void permute(const int n);
1058 
1060 }; // class ListPure
1061 
1062 
1063 
1065 
1089 #define forall_listiterators(type, it, L) \
1090  for(ListConstIterator< type > it = (L).begin(); it.valid(); ++it)
1091 
1093 
1097 #define forall_rev_listiterators(type, it, L) \
1098  for(ListConstIterator< type > it = (L).rbegin(); it.valid(); --it)
1099 
1101 
1105 #define forall_nonconst_listiterators(type, it, L) \
1106  for(ListIterator< type > it = (L).begin(); it.valid(); ++it)
1107 
1109 
1113 #define forall_rev_nonconst_listiterators(type, it, L) \
1114  for(ListIterator< type > it = (L).rbegin(); it.valid(); --it)
1115 
1117 
1121 #define forall_slistiterators(type, it, L) \
1122  for(SListConstIterator< type > it = (L).begin(); it.valid(); ++it)
1123 
1125 
1129 #define forall_nonconst_slistiterators(type, it, L) \
1130  for(SListIterator< type > it = (L).begin(); it.valid(); ++it)
1131 
1132 
1133 
1134 
1136 
1147 template<class E>
1148 class List : private ListPure<E> {
1149 
1150  int m_count;
1151 
1152 public:
1154  List() : m_count(0) { }
1155 
1157  List(const List<E> &L) : ListPure<E>(L), m_count(L.m_count) { }
1158 
1159  // destruction
1160  ~List() { }
1161 
1162  typedef E value_type;
1166 
1168  bool empty() const { return ListPure<E>::empty(); }
1169 
1170  // returns length of list
1171  int size() const { return m_count; }
1172 
1173  // returns first element of list (0 if empty)
1174  const ListConstIterator<E> begin() const { return ListPure<E>::begin(); }
1175  // returns first element of list (0 if empty)
1177 
1178  // returns iterator to one-past-last element of list
1180  // returns iterator to one-past-last element of list
1182 
1183  // returns last element of list (0 if empty)
1185  // returns last element of list (0 if empty)
1187 
1188  // returns iterator to one-before-first element of list
1190  // returns iterator to one-before-first element of list
1192 
1193  // returns reference to first element
1194  const E &front() const { return ListPure<E>::front(); }
1195  // returns reference to first element
1196  E &front() { return ListPure<E>::front(); }
1197 
1198  // returns reference to last element
1199  const E &back() const { return ListPure<E>::back(); }
1200  // returns reference to last element
1201  E &back() { return ListPure<E>::back(); }
1202 
1203  // returns cyclic successor
1205  return ListPure<E>::cyclicSucc(it);
1206  }
1207 
1208  // returns cyclic successor
1210  return ListPure<E>::cyclicSucc(it);
1211  }
1212 
1213  // returns cyclic predecessor
1215  return ListPure<E>::cyclicPred(it);
1216  }
1217 
1218  // returns cyclic predecessor
1220  return ListPure<E>::cyclicPred(it);
1221  }
1222 
1223  // returns the iterator at position pos. Note that this takes time linear in pos.
1224  ListConstIterator<E> get(int pos) const {
1225  OGDF_ASSERT(0 <= pos && pos < m_count)
1226  return ListPure<E>::get(pos);
1227  }
1228 
1229  // returns the iterator at position pos. Note that this takes time linear in pos.
1231  OGDF_ASSERT(0 <= pos && pos < m_count)
1232  return ListPure<E>::get(pos);
1233  }
1234 
1236 
1239  int pos(ListConstIterator<E> it) const {
1240  OGDF_ASSERT(it.valid())
1241  return ListPure<E>::pos(it);
1242  }
1243 
1245 
1249  return (m_count > 0) ? get(randomNumber(0,m_count-1)) : ListConstIterator<E>();
1250  }
1251 
1253 
1257  return (m_count > 0) ? get(randomNumber(0,m_count-1)) : ListIterator<E>();
1258  }
1259 
1261 
1266  const E chooseElement() const {
1267  OGDF_ASSERT(!empty());
1268  return *chooseIterator();
1269  }
1270 
1272 
1278  OGDF_ASSERT(!empty());
1279  return *chooseIterator();
1280  }
1281 
1282  // assignment
1285  m_count = L.m_count;
1286  return *this;
1287  }
1288 
1290  bool operator==(const List<E> &L) const {
1291  if(m_count != L.m_count)
1292  return false;
1293 
1294  ListElement<E> *pX = ListPure<E>::m_head, *pY = L.m_head;
1295  while(pX != 0) {
1296  if(pX->m_x != pY->m_x)
1297  return false;
1298  pX = pX->m_next;
1299  pY = pY->m_next;
1300  }
1301  return true;
1302  }
1303 
1305  bool operator!=(const List<E> &L) const {
1306  return !operator==(L);
1307  }
1308 
1309  // adds element x at beginning
1311  ++m_count;
1312  return ListPure<E>::pushFront(x);
1313  }
1314 
1315  // adds element x at end
1317  ++m_count;
1318  return ListPure<E>::pushBack(x);
1319  }
1320 
1321  // inserts x before or after it
1323  ++m_count;
1324  return ListPure<E>::insert(x,it,dir);
1325  }
1326 
1327  // inserts x before it
1329  ++m_count;
1330  return ListPure<E>::insertBefore(x,it);
1331  }
1332 
1333  // inserts x after it
1335  ++m_count;
1336  return ListPure<E>::insertAfter(x,it);
1337  }
1338 
1339  // removes first element
1340  void popFront() {
1341  --m_count;
1343  }
1344 
1345  // removes first element and returns it
1347  E el = front();
1348  popFront();
1349  return el;
1350  }
1351 
1352  // removes last element
1353  void popBack() {
1354  --m_count;
1356  }
1357 
1358  // removes last element and returns it
1360  E el = back();
1361  popBack();
1362  return el;
1363  }
1364 
1366  ListPure<E>::exchange(it1,it2);
1367  }
1368 
1370 
1375  }
1377 
1382  }
1384 
1388  ListPure<E>::moveToSucc(it,itBefore);
1389  }
1391 
1395  ListPure<E>::moveToPrec(it,itAfter);
1396  }
1397 
1399 
1403  ListPure<E>::moveToFront(it,L2);
1404  --m_count; ++L2.m_count;
1405  }
1407 
1411  ListPure<E>::moveToBack(it,L2);
1412  --m_count; ++L2.m_count;
1413  }
1414 
1416 
1421  ListPure<E>::moveToSucc(it,L2,itBefore);
1422  --m_count; ++L2.m_count;
1423  }
1425 
1430  ListPure<E>::moveToPrec(it,L2,itAfter);
1431  --m_count; ++L2.m_count;
1432  }
1433 
1434  // removes it and frees memory
1436  --m_count;
1437  ListPure<E>::del(it);
1438  }
1439 
1441  void conc(List<E> &L2) {
1442  ListPure<E>::conc(L2);
1443  m_count += L2.m_count;
1444  L2.m_count = 0;
1445  }
1446 
1448  void concFront(List<E> &L2) {
1450  m_count += L2.m_count;
1451  L2.m_count = 0;
1452  }
1453 
1455 
1458  void exchange(List<E>& L2) {
1460  int t = this->m_count;
1461  this->m_count = L2.m_count;
1462  L2.m_count = t;
1463  }
1464 
1466 
1475  ListPure<E>::split(it,L1,L2,dir);
1476  int countL = m_count, countL1 = 0;
1477  for(ListElement<E> *pX = L1.m_head; pX != 0; pX = pX->m_next)
1478  ++countL1;
1479 
1480  L1.m_count = countL1;
1481  L2.m_count = countL - countL1;
1482  if (this->m_head == 0) m_count = 0;
1483  }
1484 
1485  // reverses the order of the list elements
1487 
1488  // removes all elements from list
1489  void clear() {
1490  m_count = 0;
1492  }
1493 
1495  const ListPure<E> &getListPure() const { return *this; }
1496 
1497  // sorts list using quicksort
1498  void quicksort() {
1499  ogdf::quicksortTemplate(*this);
1500  }
1501 
1502  // sorts list using quicksort and parameterized compare element comp
1503  template<class COMPARER>
1504  void quicksort(const COMPARER &comp) {
1505  ogdf::quicksortTemplate(*this,comp);
1506  }
1507 
1508  // sorts list using bucket sort
1509  void bucketSort(int l, int h, BucketFunc<E> &f) {
1510  ListPure<E>::bucketSort(l,h,f);
1511  }
1512 
1513  // permutes elements in list randomly
1514  void permute() {
1516  }
1517 
1519  int search (const E& e) const {
1520  return ListPure<E>::search(e);
1521  }
1522 
1524  template<class COMPARER>
1525  int search (const E& e, const COMPARER &comp) const {
1526  return ListPure<E>::search(e, comp);
1527  }
1528 
1529 
1531 }; // class List
1532 
1533 
1534 
1535 template<class E>
1537 {
1538  if (m_head == m_tail) return;
1539 
1540  Array<ListElement<E> *> head(l,h,0), tail(l,h);
1541 
1542  ListElement<E> *pX;
1543  for (pX = m_head; pX; pX = pX->m_next) {
1544  int i = f.getBucket(pX->m_x);
1545  if (head[i])
1546  tail[i] = ((pX->m_prev = tail[i])->m_next = pX);
1547  else
1548  head[i] = tail[i] = pX;
1549  }
1550 
1551  ListElement<E> *pY = 0;
1552  for (int i = l; i <= h; i++) {
1553  pX = head[i];
1554  if (pX) {
1555  if (pY) {
1556  (pY->m_next = pX)->m_prev = pY;
1557  } else
1558  (m_head = pX)->m_prev = 0;
1559  pY = tail[i];
1560  }
1561  }
1562 
1563  m_tail = pY;
1564  pY->m_next = 0;
1565 }
1566 
1567 
1568 // permutes elements in list randomly; n is the length of the list
1569 template<class E>
1570 void ListPure<E>::permute(const int n)
1571 {
1572  Array<ListElement<E> *> A(n+2);
1573  A[0] = A[n+1] = 0;
1574 
1575  int i = 1;
1576  ListElement<E> *pX;
1577  for (pX = m_head; pX; pX = pX->m_next)
1578  A[i++] = pX;
1579 
1580  A.permute(1,n);
1581 
1582  for (i = 1; i <= n; i++) {
1583  pX = A[i];
1584  pX->m_next = A[i+1];
1585  pX->m_prev = A[i-1];
1586  }
1587 
1588  m_head = A[1];
1589  m_tail = A[n];
1590 }
1591 
1592 
1593 // prints list L to output stream os using delimiter delim
1594 template<class E>
1595 void print(ostream &os, const ListPure<E> &L, char delim = ' ')
1596 {
1597  ListConstIterator<E> pX = L.begin();
1598  if (pX.valid()) {
1599  os << *pX;
1600  for(++pX; pX.valid(); ++pX)
1601  os << delim << *pX;
1602  }
1603 }
1604 
1605 // prints list L to output stream os using delimiter delim
1606 template<class E>
1607 void print(ostream &os, const List<E> &L, char delim = ' ')
1608 {
1609  print(os, L.getListPure(), delim);
1610 }
1611 
1612 // prints list L to output stream os
1613 template<class E>
1614 ostream &operator<<(ostream &os, const ListPure<E> &L)
1615 {
1616  print(os,L);
1617  return os;
1618 }
1619 
1620 // prints list L to output stream os
1621 template<class E>
1622 ostream &operator<<(ostream &os, const List<E> &L)
1623 {
1624  return os << L.getListPure();
1625 }
1626 
1627 
1628 } // end namespace ogdf
1629 
1630 
1631 #endif