00001
00002
00003
00004
00005
00006
00007
00008
00042 #ifdef _MSC_VER
00043 #pragma once
00044 #endif
00045
00046 #ifndef OGDF_LIST_H
00047 #define OGDF_LIST_H
00048
00049
00050 #include <ogdf/internal/basic/list_templates.h>
00051
00052
00053 namespace ogdf {
00054
00055
00056 template<class E> class List;
00057 template<class E> class ListPure;
00058 template<class E> class ListIterator;
00059 template<class E> class ListConstIterator;
00060
00061
00063 template<class E>
00064 class ListElement {
00065 friend class ListPure<E>;
00066 friend class List<E>;
00067 friend class ListIterator<E>;
00068 friend class ListConstIterator<E>;
00069
00070 ListElement<E> *m_next;
00071 ListElement<E> *m_prev;
00072 E m_x;
00073
00075 ListElement() : m_next(0), m_prev(0) { }
00077 ListElement(const E &x) : m_next(0), m_prev(0), m_x(x) { }
00079 ListElement(const E &x, ListElement<E> *next, ListElement<E> *prev) :
00080 m_next(next), m_prev(prev), m_x(x) { }
00081
00082 OGDF_NEW_DELETE
00083 };
00084
00085
00086
00088
00094 template<class E> class ListIterator {
00095 ListElement<E> *m_pX;
00096
00097 friend class ListConstIterator<E>;
00098 friend class ListPure<E>;
00099
00101 operator ListElement<E> *() { return m_pX; }
00103 operator const ListElement<E> *() const { return m_pX; }
00104
00105 public:
00107 ListIterator() : m_pX(0) { }
00109 ListIterator(ListElement<E> *pX) : m_pX(pX) { }
00111 ListIterator(const ListIterator<E> &it) : m_pX(it.m_pX) { }
00112
00114 bool valid() const { return m_pX != 0; }
00115
00117 bool operator==(const ListIterator<E> &it) const {
00118 return m_pX == it.m_pX;
00119 }
00120
00122 bool operator!=(const ListIterator<E> &it) const {
00123 return m_pX != it.m_pX;
00124 }
00125
00127 ListIterator<E> succ() const { return m_pX->m_next; }
00128
00130 ListIterator<E> pred() const { return m_pX->m_prev; }
00131
00133 E &operator*() const { return m_pX->m_x; }
00134
00136 ListIterator<E> &operator=(const ListIterator<E> &it) {
00137 m_pX = it.m_pX;
00138 return *this;
00139 }
00140
00142 ListIterator<E> &operator++() {
00143 m_pX = m_pX->m_next;
00144 return *this;
00145 }
00146
00148 ListIterator<E> operator++(int) {
00149 ListIterator<E> it = *this;
00150 m_pX = m_pX->m_next;
00151 return it;
00152 }
00153
00155 ListIterator<E> &operator--() {
00156 m_pX = m_pX->m_prev;
00157 return *this;
00158 }
00159
00161 ListIterator<E> operator--(int) {
00162 ListIterator<E> it = *this;
00163 m_pX = m_pX->m_prev;
00164 return it;
00165 }
00166
00167 OGDF_NEW_DELETE
00168 };
00169
00170
00171
00172
00173
00174
00175
00177
00184 template<class E> class ListConstIterator {
00185 const ListElement<E> *m_pX;
00186
00187 friend class ListPure<E>;
00188
00190 operator const ListElement<E> *() { return m_pX; }
00191
00192 public:
00194 ListConstIterator() : m_pX(0) { }
00195
00197 ListConstIterator(const ListElement<E> *pX) : m_pX(pX) { }
00198
00200 ListConstIterator(const ListIterator<E> &it) : m_pX((const ListElement<E> *)it) { }
00202 ListConstIterator(const ListConstIterator &it) : m_pX(it.m_pX) { }
00203
00205 bool valid() const { return m_pX != 0; }
00206
00208 bool operator==(const ListConstIterator<E> &it) const {
00209 return m_pX == it.m_pX;
00210 }
00211
00213 bool operator!=(const ListConstIterator<E> &it) const {
00214 return m_pX != it.m_pX;
00215 }
00216
00218 ListConstIterator<E> succ() const { return m_pX->m_next; }
00219
00221 ListConstIterator<E> pred() const { return m_pX->m_prev; }
00222
00224 const E &operator*() const { return m_pX->m_x; }
00225
00227 ListConstIterator<E> &operator=(const ListConstIterator<E> &it) {
00228 m_pX = it.m_pX;
00229 return *this;
00230 }
00231
00233 ListConstIterator<E> &operator++() {
00234 m_pX = m_pX->m_next;
00235 return *this;
00236 }
00237
00239 ListConstIterator<E> operator++(int) {
00240 ListConstIterator<E> it = *this;
00241 m_pX = m_pX->m_next;
00242 return it;
00243 }
00244
00246 ListConstIterator<E> &operator--() {
00247 m_pX = m_pX->m_prev;
00248 return *this;
00249 }
00250
00252 ListConstIterator<E> operator--(int) {
00253 ListConstIterator<E> it = *this;
00254 m_pX = m_pX->m_prev;
00255 return it;
00256 }
00257
00258 OGDF_NEW_DELETE
00259 };
00260
00261
00262
00264
00271 template<class E> class ListPure {
00272 protected:
00273
00274 ListElement<E> *m_head;
00275 ListElement<E> *m_tail;
00276
00277 public:
00279 ListPure() : m_head(0), m_tail(0) { }
00280
00282 ListPure(const ListPure<E> &L) : m_head(0), m_tail(0) {
00283 copy(L);
00284 }
00285
00286
00287 ~ListPure() { clear(); }
00288
00289 typedef E value_type;
00290 typedef ListElement<E> element_type;
00291 typedef ListConstIterator<E> const_iterator;
00292 typedef ListIterator<E> iterator;
00293
00295 bool empty() const { return m_head == 0; }
00296
00298
00301 int size() const {
00302 int count = 0;
00303 for (ListElement<E> *pX = m_head; pX; pX = pX->m_next)
00304 ++count;
00305 return count;
00306 }
00307
00309
00312 const ListConstIterator<E> begin() const { return m_head; }
00314
00317 ListIterator<E> begin() { return m_head; }
00318
00320
00323 ListConstIterator<E> end() const { return ListConstIterator<E>(); }
00325
00328 ListIterator<E> end() { return ListIterator<E>(); }
00329
00331
00334 const ListConstIterator<E> rbegin() const { return m_tail; }
00336
00339 ListIterator<E> rbegin() { return m_tail; }
00340
00342
00345 ListConstIterator<E> rend() const { return ListConstIterator<E>(); }
00347
00350 ListIterator<E> rend() { return ListIterator<E>(); }
00351
00353
00356 const E &front() const {
00357 OGDF_ASSERT(m_head != 0)
00358 return m_head->m_x;
00359 }
00360
00362
00365 E &front() {
00366 OGDF_ASSERT(m_head != 0)
00367 return m_head->m_x;
00368 }
00369
00371
00374 const E &back() const {
00375 OGDF_ASSERT(m_tail != 0)
00376 return m_tail->m_x;
00377 }
00378
00380
00383 E &back() {
00384 OGDF_ASSERT(m_tail != 0)
00385 return m_tail->m_x;
00386 }
00387
00389
00392 ListConstIterator<E> cyclicSucc(ListConstIterator<E> it) const {
00393 const ListElement<E> *pX = it;
00394 return (pX->m_next) ? pX->m_next : m_head;
00395 }
00396
00398
00401 ListIterator<E> cyclicSucc(ListIterator<E> it) {
00402 OGDF_ASSERT(it.valid())
00403 ListElement<E> *pX = it;
00404 return (pX->m_next) ? pX->m_next : m_head;
00405 }
00406
00408
00411 ListConstIterator<E> cyclicPred(ListConstIterator<E> it) const {
00412 OGDF_ASSERT(it.valid())
00413 const ListElement<E> *pX = it;
00414 return (pX->m_prev) ? pX->m_prev : m_tail;
00415 }
00416
00418
00421 ListIterator<E> cyclicPred(ListIterator<E> it) {
00422 OGDF_ASSERT(it.valid())
00423 ListElement<E> *pX = it;
00424 return (pX->m_prev) ? pX->m_prev : m_tail;
00425 }
00426
00428
00431 ListConstIterator<E> get(int pos) const {
00432 ListElement<E> *pX;
00433 for(pX = m_head; pX != 0; pX = pX->m_next)
00434 if (pos-- == 0) break;
00435 return pX;
00436 }
00437
00439
00442 ListIterator<E> get(int pos) {
00443 ListElement<E> *pX;
00444 for(pX = m_head; pX != 0; pX = pX->m_next)
00445 if (pos-- == 0) break;
00446 return pX;
00447 }
00448
00450
00454 int pos(ListConstIterator<E> it) const {
00455 OGDF_ASSERT(it.valid())
00456 int p = 0;
00457 for(ListElement<E> *pX = m_head; pX != 0; pX = pX->m_next, ++p)
00458 if (pX == it) break;
00459 return p;
00460 }
00461
00462
00463 ListConstIterator<E> chooseIterator() const {
00464 return get(randomNumber(0,size()-1));
00465 }
00466
00467
00468 ListIterator<E> chooseIterator() {
00469 return get(randomNumber(0,size()-1));
00470 }
00471
00472
00473 const E chooseElement() const {
00474 return *chooseIterator();
00475 }
00476
00477
00478 E chooseElement() {
00479 return *chooseIterator();
00480 }
00481
00483 ListPure<E> &operator=(const ListPure<E> &L) {
00484 clear(); copy(L);
00485 return *this;
00486 }
00487
00489 bool operator==(const ListPure<E> &L) const {
00490 ListElement<E> *pX = m_head, *pY = L.m_head;
00491 while(pX != 0 && pY != 0) {
00492 if(pX->m_x != pY->m_x)
00493 return false;
00494 pX = pX->m_next;
00495 pY = pY->m_next;
00496 }
00497 return (pX == 0 && pY == 0);
00498 }
00499
00501 bool operator!=(const ListPure<E> &L) const {
00502 return !operator==(L);
00503 }
00504
00506 ListIterator<E> pushFront(const E &x) {
00507 ListElement<E> *pX = OGDF_NEW ListElement<E>(x,m_head,0);
00508 if (m_head)
00509 m_head = m_head->m_prev = pX;
00510 else
00511 m_head = m_tail = pX;
00512 return m_head;
00513 }
00514
00516 ListIterator<E> pushBack(const E &x) {
00517 ListElement<E> *pX = OGDF_NEW ListElement<E>(x,0,m_tail);
00518 if (m_head)
00519 m_tail = m_tail->m_next = pX;
00520 else
00521 m_tail = m_head = pX;
00522 return m_tail;
00523 }
00524
00526
00533 ListIterator<E> insert(const E &x, ListIterator<E> it, Direction dir = after) {
00534 OGDF_ASSERT(it.valid())
00535 OGDF_ASSERT(dir == after || dir == before)
00536 ListElement<E> *pY = it, *pX;
00537 if (dir == after) {
00538 ListElement<E> *pYnext = pY->m_next;
00539 pY->m_next = pX = OGDF_NEW ListElement<E>(x,pYnext,pY);
00540 if (pYnext) pYnext->m_prev = pX;
00541 else m_tail = pX;
00542 } else {
00543 ListElement<E> *pYprev = pY->m_prev;
00544 pY->m_prev = pX = OGDF_NEW ListElement<E>(x,pY,pYprev);
00545 if (pYprev) pYprev->m_next = pX;
00546 else m_head = pX;
00547 }
00548 return pX;
00549 }
00550
00552
00555 ListIterator<E> insertBefore(const E &x, ListIterator<E> it) {
00556 OGDF_ASSERT(it.valid())
00557 ListElement<E> *pY = it, *pX;
00558 ListElement<E> *pYprev = pY->m_prev;
00559 pY->m_prev = pX = OGDF_NEW ListElement<E>(x,pY,pYprev);
00560 if (pYprev) pYprev->m_next = pX;
00561 else m_head = pX;
00562 return pX;
00563 }
00564
00566
00569 ListIterator<E> insertAfter(const E &x, ListIterator<E> it) {
00570 OGDF_ASSERT(it.valid())
00571 ListElement<E> *pY = it, *pX;
00572 ListElement<E> *pYnext = pY->m_next;
00573 pY->m_next = pX = OGDF_NEW ListElement<E>(x,pYnext,pY);
00574 if (pYnext) pYnext->m_prev = pX;
00575 else m_tail = pX;
00576 return pX;
00577 }
00578
00580
00583 void popFront() {
00584 OGDF_ASSERT(m_head != 0)
00585 ListElement<E> *pX = m_head;
00586 m_head = m_head->m_next;
00587 delete pX;
00588 if (m_head) m_head->m_prev = 0;
00589 else m_tail = 0;
00590 }
00591
00593
00596 E popFrontRet() {
00597 E el = front();
00598 popFront();
00599 return el;
00600 }
00601
00603
00606 void popBack() {
00607 OGDF_ASSERT(m_tail != 0)
00608 ListElement<E> *pX = m_tail;
00609 m_tail = m_tail->m_prev;
00610 delete pX;
00611 if (m_tail) m_tail->m_next = 0;
00612 else m_head = 0;
00613 }
00614
00616
00619 E popBackRet() {
00620 E el = back();
00621 popBack();
00622 return el;
00623 }
00624
00626
00629 void del(ListIterator<E> it) {
00630 OGDF_ASSERT(it.valid())
00631 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00632 delete pX;
00633 if (pPrev) pPrev->m_next = pNext;
00634 else m_head = pNext;
00635 if (pNext) pNext->m_prev = pPrev;
00636 else m_tail = pPrev;
00637 }
00638
00640
00643 void exchange(ListIterator<E> it1, ListIterator<E> it2) {
00644 OGDF_ASSERT(it1.valid() && it2.valid() && it1 != it2)
00645 ListElement<E> *pX = it1, *pY = it2;
00646
00647 std::swap(pX->m_next,pY->m_next);
00648 std::swap(pX->m_prev,pY->m_prev);
00649
00650 if(pX->m_next == pX) {
00651 pX->m_next = pY; pY->m_prev = pX;
00652 }
00653 if(pX->m_prev == pX) {
00654 pX->m_prev = pY; pY->m_next = pX;
00655 }
00656
00657 if(pX->m_prev) pX->m_prev->m_next = pX;
00658 else m_head = pX;
00659
00660 if(pY->m_prev) pY->m_prev->m_next = pY;
00661 else m_head = pY;
00662
00663 if(pX->m_next) pX->m_next->m_prev = pX;
00664 else m_tail = pX;
00665
00666 if(pY->m_next) pY->m_next->m_prev = pY;
00667 else m_tail = pY;
00668 }
00669
00671
00674 void moveToFront(ListIterator<E> it) {
00675 OGDF_ASSERT(it.valid())
00676
00677 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00678
00679 if (!pPrev) return;
00680
00681
00682 if (pPrev) pPrev->m_next = pNext;
00683 if (pNext) pNext->m_prev = pPrev;
00684 else m_tail = pPrev;
00685
00686 pX->m_prev = 0;
00687 pX->m_next = m_head;
00688 m_head = m_head->m_prev = pX;
00689 }
00690
00692
00695 void moveToBack(ListIterator<E> it) {
00696 OGDF_ASSERT(it.valid())
00697
00698 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00699
00700 if (!pNext) return;
00701
00702
00703 if (pPrev) pPrev->m_next = pNext;
00704 else m_head = pNext;
00705 if (pNext) pNext->m_prev = pPrev;
00706
00707 pX->m_prev = m_tail;
00708 pX->m_next = 0;
00709 m_tail = m_tail->m_next = pX;
00710 }
00711
00713
00716 void moveToSucc(ListIterator<E> it, ListIterator<E> itBefore) {
00717 OGDF_ASSERT(it.valid() && itBefore.valid())
00718
00719 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00720
00721 ListElement<E> *pY = itBefore;
00722 if(pX == pY || pPrev == pY) return;
00723
00724
00725 if (pPrev) pPrev->m_next = pNext;
00726 else m_head = pNext;
00727 if (pNext) pNext->m_prev = pPrev;
00728 else m_tail = pPrev;
00729
00730 ListElement<E> *pYnext = pX->m_next = pY->m_next;
00731 (pX->m_prev = pY)->m_next = pX;
00732 if (pYnext) pYnext->m_prev = pX;
00733 else m_tail = pX;
00734 }
00735
00737
00740 void moveToPrec(ListIterator<E> it, ListIterator<E> itAfter) {
00741 OGDF_ASSERT(it.valid() && itAfter.valid())
00742
00743 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00744
00745 ListElement<E> *pY = itAfter;
00746 if(pX == pY || pNext == pY) return;
00747
00748
00749 if (pPrev) pPrev->m_next = pNext;
00750 else m_head = pNext;
00751 if (pNext) pNext->m_prev = pPrev;
00752 else m_tail = pPrev;
00753
00754 ListElement<E> *pYprev = pX->m_prev = pY->m_prev;
00755 (pX->m_next = pY)->m_prev = pX;
00756 if (pYprev) pYprev->m_next = pX;
00757 else m_head = pX;
00758 }
00759
00761
00764 void moveToFront(ListIterator<E> it, ListPure<E> &L2) {
00765 OGDF_ASSERT(it.valid())
00766 OGDF_ASSERT(this != &L2)
00767
00768 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00769 if (pPrev) pPrev->m_next = pNext;
00770 else m_head = pNext;
00771 if (pNext) pNext->m_prev = pPrev;
00772 else m_tail = pPrev;
00773
00774 pX->m_prev = 0;
00775 if ((pX->m_next = L2.m_head) != 0)
00776 L2.m_head = L2.m_head->m_prev = pX;
00777 else
00778 L2.m_head = L2.m_tail = pX;
00779 }
00780
00782
00785 void moveToBack(ListIterator<E> it, ListPure<E> &L2) {
00786 OGDF_ASSERT(it.valid())
00787 OGDF_ASSERT(this != &L2)
00788
00789 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00790 if (pPrev) pPrev->m_next = pNext;
00791 else m_head = pNext;
00792 if (pNext) pNext->m_prev = pPrev;
00793 else m_tail = pPrev;
00794
00795 pX->m_next = 0;
00796 if ((pX->m_prev = L2.m_tail) != 0)
00797 L2.m_tail = L2.m_tail->m_next = pX;
00798 else
00799 L2.m_head = L2.m_tail = pX;
00800 }
00801
00803
00807 void moveToSucc(ListIterator<E> it, ListPure<E> &L2, ListIterator<E> itBefore) {
00808 OGDF_ASSERT(it.valid() && itBefore.valid())
00809 OGDF_ASSERT(this != &L2)
00810
00811 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00812 if (pPrev) pPrev->m_next = pNext;
00813 else m_head = pNext;
00814 if (pNext) pNext->m_prev = pPrev;
00815 else m_tail = pPrev;
00816
00817 ListElement<E> *pY = itBefore;
00818 ListElement<E> *pYnext = pX->m_next = pY->m_next;
00819 (pX->m_prev = pY)->m_next = pX;
00820 if (pYnext) pYnext->m_prev = pX;
00821 else L2.m_tail = pX;
00822 }
00823
00825
00829 void moveToPrec(ListIterator<E> it, ListPure<E> &L2, ListIterator<E> itAfter) {
00830 OGDF_ASSERT(it.valid() && itAfter.valid())
00831 OGDF_ASSERT(this != &L2)
00832
00833 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00834 if (pPrev) pPrev->m_next = pNext;
00835 else m_head = pNext;
00836 if (pNext) pNext->m_prev = pPrev;
00837 else m_tail = pPrev;
00838
00839 ListElement<E> *pY = itAfter;
00840 ListElement<E> *pYprev = pX->m_prev = pY->m_prev;
00841 (pX->m_next = pY)->m_prev = pX;
00842 if (pYprev) pYprev->m_next = pX;
00843 else L2.m_head = pX;
00844 }
00845
00847 void conc(ListPure<E> &L2) {
00848 OGDF_ASSERT(this != &L2)
00849 if (m_head)
00850 m_tail->m_next = L2.m_head;
00851 else
00852 m_head = L2.m_head;
00853 if (L2.m_head) {
00854 L2.m_head->m_prev = m_tail;
00855 m_tail = L2.m_tail;
00856 }
00857 L2.m_head = L2.m_tail = 0;
00858 }
00859
00861 void concFront(ListPure<E> &L2) {
00862 OGDF_ASSERT(this != &L2)
00863 if (m_head)
00864 m_head->m_prev = L2.m_tail;
00865 else
00866 m_tail = L2.m_tail;
00867 if (L2.m_head) {
00868 L2.m_tail->m_next = m_head;
00869 m_head = L2.m_head;
00870 }
00871 L2.m_head = L2.m_tail = 0;
00872 }
00873
00875
00878 void exchange(ListPure<E>& L2) {
00879 ListElement<E>* t;
00880 t = this->m_head;
00881 this->m_head = L2.m_head;
00882 L2.m_head = t;
00883 t = this->m_tail;
00884 this->m_tail = L2.m_tail;
00885 L2.m_tail = t;
00886 }
00887
00889
00898 void split(ListIterator<E> it,ListPure<E> &L1,ListPure<E> &L2,Direction dir = before) {
00899 if (&L1 != this) L1.clear();
00900 if (&L2 != this) L2.clear();
00901
00902 if (it.valid()){
00903 L1.m_head = m_head;
00904 L2.m_tail = m_tail;
00905 if (dir == before){
00906 L2.m_head = it;
00907 L1.m_tail = L2.m_head->m_prev;
00908 }
00909 else {
00910 L1.m_tail = it;
00911 L2.m_head = L1.m_tail->m_next;
00912 }
00913 L2.m_head->m_prev = L1.m_tail->m_next = 0;
00914
00915 } else {
00916 L1.m_head = L1.m_tail = 0;
00917 L2.m_head = m_head;
00918 L2.m_tail = m_tail;
00919 }
00920
00921 if (this != &L1 && this != &L2) {
00922 m_head = m_tail = 0;
00923 }
00924 }
00925
00927 void splitAfter(ListIterator<E> it, ListPure<E> &L2) {
00928 OGDF_ASSERT(it.valid())
00929 OGDF_ASSERT(this != &L2)
00930 L2.clear();
00931 ListElement<E> *pX = it;
00932 if (pX != m_tail) {
00933 (L2.m_head = pX->m_next)->m_prev = 0;
00934 pX->m_next = 0;
00935 L2.m_tail = m_tail;
00936 m_tail = pX;
00937 }
00938 }
00939
00941 void splitBefore(ListIterator<E> it, ListPure<E> &L2) {
00942 OGDF_ASSERT(it.valid())
00943 OGDF_ASSERT(this != &L2)
00944 L2.clear();
00945 ListElement<E> *pX = it;
00946 L2.m_head = pX; L2.m_tail = m_tail;
00947 if ((m_tail = pX->m_prev) == 0)
00948 m_head = 0;
00949 else
00950 m_tail->m_next = 0;
00951 pX->m_prev = 0;
00952 }
00953
00955 void reverse() {
00956 ListElement<E> *pX = m_head;
00957 m_head = m_tail;
00958 m_tail = pX;
00959 while(pX) {
00960 ListElement<E> *pY = pX->m_next;
00961 pX->m_next = pX->m_prev;
00962 pX = pX->m_prev = pY;
00963 }
00964 }
00965
00967 void clear() {
00968 if (m_head == 0) return;
00969
00970 #if (_MSC_VER == 1100)
00971
00972
00973 while (!empty())
00974 popFront();
00975
00976 #else
00977
00978 if (doDestruction((E*)0)) {
00979 for(ListElement<E> *pX = m_head; pX != 0; pX = pX->m_next)
00980 pX->m_x.~E();
00981 }
00982 OGDF_ALLOCATOR::deallocateList(sizeof(ListElement<E>),m_head,m_tail);
00983
00984 #endif
00985
00986 m_head = m_tail = 0;
00987 }
00988
00990 void quicksort() {
00991 ogdf::quicksortTemplate(*this);
00992 }
00993
00995 template<class COMPARER>
00996 void quicksort(const COMPARER &comp) {
00997 ogdf::quicksortTemplate(*this,comp);
00998 }
00999
01001
01008 void bucketSort(int l, int h, BucketFunc<E> &f);
01009
01011 void permute() {
01012 permute(size());
01013 }
01014
01016 int search (const E& e) const {
01017 int x = 0;
01018 for(ListConstIterator<E> i = begin(); i.valid(); ++i, ++x)
01019 if(*i == e) return x;
01020 return -1;
01021 }
01022
01024 template<class COMPARER>
01025 int search (const E& e, const COMPARER &comp) const {
01026 int x = 0;
01027 for(ListConstIterator<E> i = begin(); i.valid(); ++i, ++x)
01028 if(comp.equal(*i,e)) return x;
01029 return -1;
01030 }
01031
01032 protected:
01033 void copy(const ListPure<E> &L) {
01034 for(ListElement<E> *pX = L.m_head; pX != 0; pX = pX->m_next)
01035 pushBack(pX->m_x);
01036 }
01037
01038 void permute(const int n);
01039
01040 OGDF_NEW_DELETE
01041 };
01042
01043
01044
01046
01070 #define forall_listiterators(type, it, L) \
01071 for(ListConstIterator< type > it = (L).begin(); it.valid(); ++it)
01072
01074
01078 #define forall_rev_listiterators(type, it, L) \
01079 for(ListConstIterator< type > it = (L).rbegin(); it.valid(); --it)
01080
01082
01086 #define forall_nonconst_listiterators(type, it, L) \
01087 for(ListIterator< type > it = (L).begin(); it.valid(); ++it)
01088
01090
01094 #define forall_rev_nonconst_listiterators(type, it, L) \
01095 for(ListIterator< type > it = (L).rbegin(); it.valid(); --it)
01096
01098
01102 #define forall_slistiterators(type, it, L) \
01103 for(SListConstIterator< type > it = (L).begin(); it.valid(); ++it)
01104
01106
01110 #define forall_nonconst_slistiterators(type, it, L) \
01111 for(SListIterator< type > it = (L).begin(); it.valid(); ++it)
01112
01113
01114
01115
01117
01126 template<class E>
01127 class List : private ListPure<E> {
01128
01129 int m_count;
01130
01131 public:
01133 List() : m_count(0) { }
01134
01136 List(const List<E> &L) : ListPure<E>(L), m_count(L.m_count) { }
01137
01138
01139 ~List() { }
01140
01141 typedef E value_type;
01142 typedef ListElement<E> element_type;
01143 typedef ListConstIterator<E> const_iterator;
01144 typedef ListIterator<E> iterator;
01145
01147 bool empty() const { return ListPure<E>::empty(); }
01148
01149
01150 int size() const { return m_count; }
01151
01152
01153 const ListConstIterator<E> begin() const { return ListPure<E>::begin(); }
01154
01155 ListIterator<E> begin() { return ListPure<E>::begin(); }
01156
01157
01158 ListConstIterator<E> end() const { return ListConstIterator<E>(); }
01159
01160 ListIterator<E> end() { return ListIterator<E>(); }
01161
01162
01163 const ListConstIterator<E> rbegin() const { return ListPure<E>::rbegin(); }
01164
01165 ListIterator<E> rbegin() { return ListPure<E>::rbegin(); }
01166
01167
01168 ListConstIterator<E> rend() const { return ListConstIterator<E>(); }
01169
01170 ListIterator<E> rend() { return ListIterator<E>(); }
01171
01172
01173 const E &front() const { return ListPure<E>::front(); }
01174
01175 E &front() { return ListPure<E>::front(); }
01176
01177
01178 const E &back() const { return ListPure<E>::back(); }
01179
01180 E &back() { return ListPure<E>::back(); }
01181
01182
01183 ListConstIterator<E> cyclicSucc(ListConstIterator<E> it) const {
01184 return ListPure<E>::cyclicSucc(it);
01185 }
01186
01187
01188 ListIterator<E> cyclicSucc(ListIterator<E> it) {
01189 return ListPure<E>::cyclicSucc(it);
01190 }
01191
01192
01193 ListConstIterator<E> cyclicPred(ListConstIterator<E> it) const {
01194 return ListPure<E>::cyclicPred(it);
01195 }
01196
01197
01198 ListIterator<E> cyclicPred(ListIterator<E> it) {
01199 return ListPure<E>::cyclicPred(it);
01200 }
01201
01202
01203 ListConstIterator<E> get(int pos) const {
01204 OGDF_ASSERT(0 <= pos && pos < m_count)
01205 return ListPure<E>::get(pos);
01206 }
01207
01208
01209 ListIterator<E> get(int pos) {
01210 OGDF_ASSERT(0 <= pos && pos < m_count)
01211 return ListPure<E>::get(pos);
01212 }
01213
01214
01215 int pos(ListConstIterator<E> it) const {
01216 return ListPure<E>::pos(it);
01217 }
01218
01219
01220 ListConstIterator<E> chooseIterator() const {
01221 return get(randomNumber(0,m_count-1));
01222 }
01223
01224
01225 ListIterator<E> chooseIterator() {
01226 return get(randomNumber(0,m_count-1));
01227 }
01228
01229
01230 const E chooseElement() const {
01231 return *chooseIterator();
01232 }
01233
01234
01235 E chooseElement() {
01236 return *chooseIterator();
01237 }
01238
01239
01240 List<E> &operator=(const List<E> &L) {
01241 ListPure<E>::operator=(L);
01242 m_count = L.m_count;
01243 return *this;
01244 }
01245
01247 bool operator==(const List<E> &L) const {
01248 if(m_count != L.m_count)
01249 return false;
01250
01251 ListElement<E> *pX = ListPure<E>::m_head, *pY = L.m_head;
01252 while(pX != 0) {
01253 if(pX->m_x != pY->m_x)
01254 return false;
01255 pX = pX->m_next;
01256 pY = pY->m_next;
01257 }
01258 return true;
01259 }
01260
01262 bool operator!=(const List<E> &L) const {
01263 return !operator==(L);
01264 }
01265
01266
01267 ListIterator<E> pushFront(const E &x) {
01268 ++m_count;
01269 return ListPure<E>::pushFront(x);
01270 }
01271
01272
01273 ListIterator<E> pushBack(const E &x) {
01274 ++m_count;
01275 return ListPure<E>::pushBack(x);
01276 }
01277
01278
01279 ListIterator<E> insert(const E &x, ListIterator<E> it, Direction dir = after) {
01280 ++m_count;
01281 return ListPure<E>::insert(x,it,dir);
01282 }
01283
01284
01285 ListIterator<E> insertBefore(const E &x, ListIterator<E> it) {
01286 ++m_count;
01287 return ListPure<E>::insertBefore(x,it);
01288 }
01289
01290
01291 ListIterator<E> insertAfter(const E &x, ListIterator<E> it) {
01292 ++m_count;
01293 return ListPure<E>::insertAfter(x,it);
01294 }
01295
01296
01297 void popFront() {
01298 --m_count;
01299 ListPure<E>::popFront();
01300 }
01301
01302
01303 E popFrontRet() {
01304 E el = front();
01305 popFront();
01306 return el;
01307 }
01308
01309
01310 void popBack() {
01311 --m_count;
01312 ListPure<E>::popBack();
01313 }
01314
01315
01316 E popBackRet() {
01317 E el = back();
01318 popBack();
01319 return el;
01320 }
01321
01322 void exchange(ListIterator<E> it1, ListIterator<E> it2) {
01323 ListPure<E>::exchange(it1,it2);
01324 }
01325
01327
01330 void moveToFront(ListIterator<E> it) {
01331 ListPure<E>::moveToFront(it);
01332 }
01334
01337 void moveToBack(ListIterator<E> it) {
01338 ListPure<E>::moveToBack(it);
01339 }
01341
01344 void moveToSucc(ListIterator<E> it, ListIterator<E> itBefore) {
01345 ListPure<E>::moveToSucc(it,itBefore);
01346 }
01348
01351 void moveToPrec(ListIterator<E> it, ListIterator<E> itAfter) {
01352 ListPure<E>::moveToPrec(it,itAfter);
01353 }
01354
01356
01359 void moveToFront(ListIterator<E> it, List<E> &L2) {
01360 ListPure<E>::moveToFront(it,L2);
01361 --m_count; ++L2.m_count;
01362 }
01364
01367 void moveToBack(ListIterator<E> it, List<E> &L2) {
01368 ListPure<E>::moveToBack(it,L2);
01369 --m_count; ++L2.m_count;
01370 }
01371
01373
01377 void moveToSucc(ListIterator<E> it, List<E> &L2, ListIterator<E> itBefore) {
01378 ListPure<E>::moveToSucc(it,L2,itBefore);
01379 --m_count; ++L2.m_count;
01380 }
01382
01386 void moveToPrec(ListIterator<E> it, List<E> &L2, ListIterator<E> itAfter) {
01387 ListPure<E>::moveToPrec(it,L2,itAfter);
01388 --m_count; ++L2.m_count;
01389 }
01390
01391
01392 void del(ListIterator<E> it) {
01393 --m_count;
01394 ListPure<E>::del(it);
01395 }
01396
01398 void conc(List<E> &L2) {
01399 ListPure<E>::conc(L2);
01400 m_count += L2.m_count;
01401 L2.m_count = 0;
01402 }
01403
01405 void concFront(List<E> &L2) {
01406 ListPure<E>::concFront(L2);
01407 m_count += L2.m_count;
01408 L2.m_count = 0;
01409 }
01410
01412
01415 void exchange(List<E>& L2) {
01416 ListPure<E>::exchange(L2);
01417 int t = this->m_count;
01418 this->m_count = L2.m_count;
01419 L2.m_count = t;
01420 }
01421
01423
01431 void split(ListIterator<E> it,List<E> &L1,List<E> &L2,Direction dir = before) {
01432 ListPure<E>::split(it,L1,L2,dir);
01433 int countL = m_count, countL1 = 0;
01434 for(ListElement<E> *pX = L1.m_head; pX != 0; pX = pX->m_next)
01435 ++countL1;
01436
01437 L1.m_count = countL1;
01438 L2.m_count = countL - countL1;
01439 if (this->m_head == 0) m_count = 0;
01440 }
01441
01442
01443 void reverse() { ListPure<E>::reverse(); }
01444
01445
01446 void clear() {
01447 m_count = 0;
01448 ListPure<E>::clear();
01449 }
01450
01452 const ListPure<E> &getListPure() const { return *this; }
01453
01454
01455 void quicksort() {
01456 ogdf::quicksortTemplate(*this);
01457 }
01458
01459
01460 template<class COMPARER>
01461 void quicksort(const COMPARER &comp) {
01462 ogdf::quicksortTemplate(*this,comp);
01463 }
01464
01465
01466 void bucketSort(int l, int h, BucketFunc<E> &f) {
01467 ListPure<E>::bucketSort(l,h,f);
01468 }
01469
01470
01471 void permute() {
01472 ListPure<E>::permute(m_count);
01473 }
01474
01476 int search (const E& e) const {
01477 return ListPure<E>::search(e);
01478 }
01479
01481 template<class COMPARER>
01482 int search (const E& e, const COMPARER &comp) const {
01483 return ListPure<E>::search(e, comp);
01484 }
01485
01486
01487 OGDF_NEW_DELETE
01488 };
01489
01490
01491
01492 template<class E>
01493 void ListPure<E>::bucketSort(int l, int h, BucketFunc<E> &f)
01494 {
01495 if (m_head == m_tail) return;
01496
01497 Array<ListElement<E> *> head(l,h,0), tail(l,h);
01498
01499 ListElement<E> *pX;
01500 for (pX = m_head; pX; pX = pX->m_next) {
01501 int i = f.getBucket(pX->m_x);
01502 if (head[i])
01503 tail[i] = ((pX->m_prev = tail[i])->m_next = pX);
01504 else
01505 head[i] = tail[i] = pX;
01506 }
01507
01508 ListElement<E> *pY = 0;
01509 for (int i = l; i <= h; i++) {
01510 pX = head[i];
01511 if (pX) {
01512 if (pY) {
01513 (pY->m_next = pX)->m_prev = pY;
01514 } else
01515 (m_head = pX)->m_prev = 0;
01516 pY = tail[i];
01517 }
01518 }
01519
01520 m_tail = pY;
01521 pY->m_next = 0;
01522 }
01523
01524
01525
01526 template<class E>
01527 void ListPure<E>::permute(const int n)
01528 {
01529 Array<ListElement<E> *> A(n+2);
01530 A[0] = A[n+1] = 0;
01531
01532 int i = 1;
01533 ListElement<E> *pX;
01534 for (pX = m_head; pX; pX = pX->m_next)
01535 A[i++] = pX;
01536
01537 A.permute(1,n);
01538
01539 for (i = 1; i <= n; i++) {
01540 pX = A[i];
01541 pX->m_next = A[i+1];
01542 pX->m_prev = A[i-1];
01543 }
01544
01545 m_head = A[1];
01546 m_tail = A[n];
01547 }
01548
01549
01550
01551 template<class E>
01552 void print(ostream &os, const ListPure<E> &L, char delim = ' ')
01553 {
01554 ListConstIterator<E> pX = L.begin();
01555 if (pX.valid()) {
01556 os << *pX;
01557 for(++pX; pX.valid(); ++pX)
01558 os << delim << *pX;
01559 }
01560 }
01561
01562
01563 template<class E>
01564 void print(ostream &os, const List<E> &L, char delim = ' ')
01565 {
01566 print(os, L.getListPure(), delim);
01567 }
01568
01569
01570 template<class E>
01571 ostream &operator<<(ostream &os, const ListPure<E> &L)
01572 {
01573 print(os,L);
01574 return os;
01575 }
01576
01577
01578 template<class E>
01579 ostream &operator<<(ostream &os, const List<E> &L)
01580 {
01581 return os << L.getListPure();
01582 }
01583
01584
01585 }
01586
01587
01588 #endif