Open
Graph Drawing
Framework

 v.2007.11
 

SList.h

Go to the documentation of this file.
00001 /*
00002  * $Revision: 1.5 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2007-11-08 16:10:37 +0100 (Do, 08 Nov 2007) $ 
00007  ***************************************************************/
00008  
00053 #ifdef _MSC_VER
00054 #pragma once
00055 #endif
00056 
00057 #ifndef OGDF_SLIST_H
00058 #define OGDF_SLIST_H
00059 
00060 
00061 #include <ogdf/internal/basic/list_templates.h>
00062 
00063 
00064 namespace ogdf {
00065 
00066 
00067 template<class E> class SListPure;
00068 template<class E> class StackPure;
00069 template<class E> class SListIterator;
00070 template<class E> class SListConstIterator;
00071 
00072 
00074 template<class E>
00075 class SListElement {
00076     friend class SListPure<E>;
00077     friend class StackPure<E>;
00078     friend class SListIterator<E>;
00079     friend class SListConstIterator<E>;
00080 
00081     SListElement<E> *m_next; 
00082     E m_x; 
00083 
00085     SListElement() : m_next(0) { }
00087     SListElement(const E &x) : m_next(0), m_x(x) { }
00089     SListElement(const E &x, SListElement<E> *next) :
00090         m_next(next), m_x(x) { }
00091     
00092     OGDF_NEW_DELETE
00093 }; // class SListElement
00094 
00095 
00096 
00098 
00104 template<class E> class SListIterator {
00105     SListElement<E> *m_pX; 
00106 
00107     friend class SListConstIterator<E>;
00108     friend class SListPure<E>;
00109 
00111     operator SListElement<E> *() { return m_pX; }
00113     operator const SListElement<E> *() const { return m_pX; }
00114 
00115 public:
00117     SListIterator() : m_pX(0) { }
00119     SListIterator(SListElement<E> *pX) : m_pX(pX) { }
00121     SListIterator(const SListIterator<E> &it) : m_pX(it.m_pX) { }
00122 
00124     bool valid() const { return m_pX != 0; }
00125 
00127     bool operator==(const SListIterator<E> &it) const {
00128         return m_pX == it.m_pX;
00129     }
00130 
00132     bool operator!=(const SListIterator<E> &it) const {
00133         return m_pX != it.m_pX;
00134     }
00135 
00137     SListIterator<E> succ() const { return m_pX->m_next; }
00138 
00140     E &operator*() const { return m_pX->m_x; }
00141 
00143     SListIterator<E> &operator=(const SListIterator<E> &it) {
00144         m_pX = it.m_pX;
00145         return *this;
00146     }
00147 
00149     SListIterator<E> &operator++() {
00150         m_pX = m_pX->m_next;
00151         return *this;
00152     }
00153 
00155     SListIterator<E> operator++(int) {
00156         SListIterator<E> it = *this;
00157         m_pX = m_pX->m_next;
00158         return it;
00159     }
00160 
00161     OGDF_NEW_DELETE
00162 }; // class SListIterator
00163 
00164 
00165 
00167 
00174 template<class E> class SListConstIterator {
00175     const SListElement<E> *m_pX; 
00176 
00177     friend class SListPure<E>;
00178 
00180     operator const SListElement<E> *() { return m_pX; }
00181 
00182 public:
00184     SListConstIterator() : m_pX(0) { }
00185     
00187     SListConstIterator(const SListElement<E> *pX) : m_pX(pX) { }
00188     
00190     SListConstIterator(const SListIterator<E> &it) : m_pX((const SListElement<E> *)it) { }
00192     SListConstIterator(const SListConstIterator &it) : m_pX(it.m_pX) { }
00193 
00195     bool valid() const { return m_pX != 0; }
00196 
00198     bool operator==(const SListConstIterator<E> &it) const {
00199         return m_pX == it.m_pX;
00200     }
00201 
00203     bool operator!=(const SListConstIterator<E> &it) const {
00204         return m_pX != it.m_pX;
00205     }
00206 
00208     SListConstIterator<E> succ() const { return m_pX->m_next; }
00209 
00211     const E &operator*() const { return m_pX->m_x; }
00212 
00214     SListConstIterator<E> &operator=(const SListConstIterator<E> &it) {
00215         m_pX = it.m_pX;
00216         return *this;
00217     }
00218 
00219 
00221     SListConstIterator<E> &operator++() {
00222         m_pX = m_pX->m_next;
00223         return *this;
00224     }
00225 
00227     SListConstIterator<E> operator++(int) {
00228         SListConstIterator<E> it = *this;
00229         m_pX = m_pX->m_next;
00230         return it;
00231     }
00232 
00233     OGDF_NEW_DELETE
00234 }; // class SListConstIterator
00235 
00236 
00238 
00245 template<class E> class SListPure {
00246     SListElement<E> *m_head; 
00247     SListElement<E> *m_tail; 
00248 
00249 public:
00251     SListPure() : m_head(0), m_tail(0) { }
00252     
00254     SListPure(const SListPure<E> &L) : m_head(0), m_tail(0) {
00255         copy(L);
00256     }
00257 
00258     // destruction
00259     ~SListPure() { clear(); }
00260 
00261     typedef E value_type;
00262     typedef SListElement<E> element_type;
00263     typedef SListConstIterator<E> const_iterator;
00264     typedef SListIterator<E> iterator;
00265 
00267     bool empty() const { return m_head == 0; }
00268 
00270 
00273     int size() const {
00274         int count = 0;
00275         for (SListElement<E> *pX = m_head; pX; pX = pX->m_next)
00276             ++count;
00277         return count;
00278     }
00279 
00281 
00284     SListConstIterator<E> begin() const { return m_head; }
00285 
00287 
00290     SListIterator<E> begin() { return m_head; }
00291 
00293 
00296     SListConstIterator<E> end() const { return SListConstIterator<E>(); }
00297 
00299 
00302     SListIterator<E> end() { return SListIterator<E>(); }
00303 
00305 
00308     SListConstIterator<E> rbegin() const { return m_tail; }
00309 
00311 
00314     SListIterator<E> rbegin() { return m_tail; }
00315 
00316 
00318 
00321     SListConstIterator<E> get(int pos) const {
00322         SListElement<E> *pX;
00323         for(pX = m_head; pX != 0; pX = pX->m_next)
00324             if (pos-- == 0) break;
00325         return pX;
00326     }
00327 
00329 
00332     SListIterator<E> get(int pos) {
00333         SListElement<E> *pX;
00334         for(pX = m_head; pX != 0; pX = pX->m_next)
00335             if (pos-- == 0) break;
00336         return pX;
00337     }
00338 
00340 
00344     int pos(SListConstIterator<E> it) const {
00345         OGDF_ASSERT(it.valid())
00346         int p = 0;
00347         for(SListElement<E> *pX = m_head; pX != 0; pX = pX->m_next, ++p)
00348             if (pX == it) break;
00349         return p;
00350     }
00351 
00352     
00354 
00357     const E &front() const {
00358         OGDF_ASSERT(m_head != 0)
00359         return m_head->m_x;
00360     }
00361 
00363 
00366     E &front() {
00367         OGDF_ASSERT(m_head != 0)
00368         return m_head->m_x;
00369     }
00370 
00372 
00375     const E &back() const {
00376         OGDF_ASSERT(m_tail != 0)
00377         return m_tail->m_x;
00378     }
00379 
00381 
00384     E &back() {
00385         OGDF_ASSERT(m_tail != 0)
00386         return m_tail->m_x;
00387     }
00388 
00390 
00393     SListConstIterator<E> cyclicSucc(SListConstIterator<E> it) const {
00394         const SListElement<E> *pX = it;
00395         return (pX->m_next) ? pX->m_next : m_head;
00396     }
00397 
00399 
00402     SListIterator<E> cyclicSucc(SListIterator<E> it) {
00403         SListElement<E> *pX = it;
00404         return (pX->m_next) ? pX->m_next : m_head;
00405     }
00406 
00408     SListPure<E> &operator=(const SListPure<E> &L) {
00409         clear(); copy(L);
00410         return *this;
00411     }
00412 
00414     SListIterator<E> pushFront(const E &x) {
00415         m_head = OGDF_NEW SListElement<E>(x,m_head);
00416         if (m_tail == 0) m_tail = m_head;
00417         return m_head;
00418     }
00419 
00421     SListIterator<E> pushBack(const E &x) {
00422         SListElement<E> *pNew = OGDF_NEW SListElement<E>(x);
00423         if (m_head == 0)
00424             m_head = m_tail = pNew;
00425         else
00426             m_tail = m_tail->m_next = pNew;
00427         return m_tail;
00428     }
00429 
00431 
00434     SListIterator<E> insertAfter(const E &x, SListIterator<E> itBefore) {
00435         SListElement<E> *pBefore = itBefore;
00436         OGDF_ASSERT(pBefore != 0)
00437         SListElement<E> *pNew = OGDF_NEW SListElement<E>(x,pBefore->m_next);
00438         if (pBefore == m_tail) m_tail = pNew;
00439         return (pBefore->m_next = pNew);
00440     }
00441 
00443 
00446     void popFront() {
00447         OGDF_ASSERT(m_head != 0)
00448         SListElement<E> *pX = m_head;
00449         if ((m_head = m_head->m_next) == 0) m_tail = 0;
00450         delete pX;
00451     }
00452 
00454 
00457     E popFrontRet() {
00458         E el = front(); 
00459         popFront();
00460         return el;
00461     }
00462 
00464 
00467     void delSucc(SListIterator<E> itBefore) {
00468         SListElement<E> *pBefore = itBefore;
00469         OGDF_ASSERT(pBefore != 0)
00470         SListElement<E> *pDel = pBefore->m_next;
00471         OGDF_ASSERT(pDel != 0)
00472         if ((pBefore->m_next = pDel->m_next) == 0) m_tail = pBefore;
00473         delete pDel;
00474     }
00475 
00477     void moveFrontToFront(SListPure<E> &L2) {
00478         OGDF_ASSERT(m_head != 0)
00479         OGDF_ASSERT(this != &L2)
00480         SListElement<E> *pX = m_head;
00481         if ((m_head = m_head->m_next) == 0) m_tail = 0;
00482         pX->m_next = L2.m_head;
00483         L2.m_head = pX;
00484         if (L2.m_tail == 0) L2.m_tail = L2.m_head;
00485     }
00486 
00488     void moveFrontToBack(SListPure<E> &L2) {
00489         OGDF_ASSERT(m_head != 0)
00490         OGDF_ASSERT(this != &L2)
00491         SListElement<E> *pX = m_head;
00492         if ((m_head = m_head->m_next) == 0) m_tail = 0;
00493         pX->m_next = 0;
00494         if (L2.m_head == 0)
00495             L2.m_head = L2.m_tail = pX;
00496         else
00497             L2.m_tail = L2.m_tail->m_next = pX;
00498     }
00499 
00501 
00504     void moveFrontToSucc(SListPure<E> &L2, SListIterator<E> itBefore) {
00505         OGDF_ASSERT(m_head != 0)
00506         OGDF_ASSERT(this != &L2)
00507         SListElement<E> *pBefore = itBefore;
00508         SListElement<E> *pX = m_head;
00509         if ((m_head = m_head->m_next) == 0) m_tail = 0;
00510         pX->m_next = pBefore->m_next;
00511         pBefore->m_next = pX;
00512         if (pBefore == L2.m_tail) L2.m_tail = pX;
00513     }
00514 
00516     void clear() {
00517         if (m_head == 0) return;
00518 
00519 #if (_MSC_VER == 1100)
00520 // workaround for bug in Visual Studio 5.0
00521 
00522         while (!empty())
00523             popFront();
00524 
00525 #else
00526 
00527         if (doDestruction((E*)0)) {
00528             for(SListElement<E> *pX = m_head; pX != 0; pX = pX->m_next)
00529                 pX->m_x.~E();
00530         }
00531         g_memory.deallocateList(m_head,m_tail,sizeof(SListElement<E>));
00532 
00533 #endif
00534 
00535         m_head = m_tail = 0;
00536     }
00537 
00539     void conc(SListPure<E> &L2) {
00540         if (m_head)
00541             m_tail->m_next = L2.m_head;
00542         else
00543             m_head = L2.m_head;
00544         if (L2.m_tail != 0) m_tail = L2.m_tail;
00545         L2.m_head = L2.m_tail = 0;
00546     }
00547 
00549     void reverse() {
00550         SListElement<E> *p, *pNext, *pPred = 0;
00551         for(p = m_head; p; p = pNext) {
00552             pNext = p->m_next;
00553             p->m_next = pPred;
00554             pPred = p;
00555         }
00556         ogdf::swap(m_head,m_tail);
00557     }
00558 
00560     const SListPure<E> &getListPure() const { return *this; }
00561 
00563     void quicksort() {
00564         ogdf::quicksortTemplate(*this);
00565     }
00566 
00568     void quicksort(Comparer<E> &comp) {
00569         ogdf::quicksortTemplate(*this,comp);
00570     }
00571 
00573     template<class C>
00574     void quicksortCT(C &comp) {
00575         ogdf::quicksortCTTemplate(*this,comp);
00576     }
00577 
00579 
00586     void bucketSort(int l, int h, BucketFunc<E> &f);
00587 
00589     void bucketSort(BucketFunc<E> &f);
00590 
00592     void permute() {
00593         permute(size());
00594     }
00595 
00596 protected:
00597     void copy(const SListPure<E> &L) {
00598         for(SListElement<E> *pX = L.m_head; pX != 0; pX = pX->m_next)
00599             pushBack(pX->m_x);
00600     }
00601 
00602     void permute(const int n);
00603 
00604     OGDF_NEW_DELETE
00605 }; // class SListPure
00606 
00607 
00608 
00610 
00617 template<class E>
00618 class SList : private SListPure<E> {
00619 
00620     int m_count; 
00621 
00622 public:
00624     SList() : m_count(0) { }
00625     
00627     SList(const SList<E> &L) : SListPure<E>(L), m_count(L.m_count) { }
00628 
00629     // destruction
00630     ~SList() { }
00631 
00632     typedef E value_type;
00633     typedef SListElement<E> element_type;
00634     typedef SListConstIterator<E> const_iterator;
00635     typedef SListIterator<E> iterator;
00636 
00638     bool empty() const { return SListPure<E>::empty(); }
00639 
00641     int size() const { return m_count; }
00642 
00644 
00647     const SListConstIterator<E> begin() const { return SListPure<E>::begin(); }
00648 
00650 
00653     SListIterator<E> begin() { return SListPure<E>::begin(); }
00654 
00656 
00659     SListConstIterator<E> end() const { return SListConstIterator<E>(); }
00660 
00662 
00665     SListIterator<E> end() { return SListIterator<E>(); }
00666 
00668 
00671     const SListConstIterator<E> rbegin() const { return SListPure<E>::rbegin(); }
00672 
00674 
00677     SListIterator<E> rbegin() { return SListPure<E>::rbegin(); }
00678 
00679 
00681 
00684     SListConstIterator<E> get(int pos) const {
00685         return SListPure<E>::get(pos);
00686     }
00687 
00689 
00692     SListIterator<E> get(int pos) {
00693         return SListPure<E>::get(pos);
00694     }
00695 
00697 
00701     int pos(SListConstIterator<E> it) const {
00702         return SListPure<E>::pos(it);;
00703     }
00704 
00705     
00707 
00710     const E &front() const { return SListPure<E>::front(); }
00711 
00713 
00716     E &front() { return SListPure<E>::front(); }
00717 
00719 
00722     const E &back() const { return SListPure<E>::back(); }
00723 
00725 
00728     E &back() { return SListPure<E>::back(); }
00729 
00731 
00734     SListConstIterator<E> cyclicSucc(SListConstIterator<E> it) const {
00735         return SListPure<E>::cyclicSucc(it);
00736     }
00737 
00739 
00742     SListIterator<E> cyclicSucc(SListIterator<E> it) {
00743         return SListPure<E>::cyclicSucc(it);
00744     }
00745 
00747     SList<E> &operator=(const SList<E> &L) {
00748         SListPure<E>::operator=(L);
00749         m_count = L.m_count;
00750         return *this;
00751     }
00752 
00754     SListIterator<E> pushFront(const E &x) {
00755         ++m_count;
00756         return SListPure<E>::pushFront(x);
00757     }
00758 
00760     SListIterator<E> pushBack(const E &x) {
00761         ++m_count;
00762         return SListPure<E>::pushBack(x);
00763     }
00764 
00766 
00769     SListIterator<E> insertAfter(const E &x, SListIterator<E> itBefore) {
00770         ++m_count;
00771         return SListPure<E>::insertAfter(x, itBefore);
00772     }
00773 
00775 
00778     void popFront() {
00779         --m_count;
00780         SListPure<E>::popFront();
00781     }
00782 
00784 
00787     E popFrontRet() {
00788         E el = front(); 
00789         popFront();
00790         return el;
00791     }
00792 
00794 
00797     void delSucc(SListIterator<E> itBefore) {
00798         --m_count;
00799         SListPure<E>::delSucc(itBefore);
00800     }
00801 
00803     void moveFrontToFront(SList<E> &L2) {
00804         SListPure<E>::moveFrontToFront(L2);
00805         --m_count; ++L2.m_count;
00806     }
00807 
00809     void moveFrontToBack(SList<E> &L2) {
00810         SListPure<E>::moveFrontToBack(L2);
00811         --m_count; ++L2.m_count;
00812     }
00813 
00815 
00818     void moveFrontToSucc(SList<E> &L2, SListIterator<E> itBefore) {
00819         SListPure<E>::moveFrontToSucc(L2,itBefore);
00820         --m_count; ++L2.m_count;
00821     }
00822 
00824     void clear() {
00825         m_count = 0;
00826         SListPure<E>::clear();
00827     }
00828 
00830     void conc(SList<E> &L2) {
00831         SListPure<E>::conc(L2);
00832         m_count += L2.m_count;
00833         L2.m_count = 0;
00834     }
00835 
00837     void reverse() {
00838         SListPure<E>::reverse();
00839     }
00840 
00842     const SListPure<E> &getListPure() const { return *this; }
00843 
00845     void quicksort() {
00846         ogdf::quicksortTemplate(*this);
00847     }
00848 
00850     void quicksort(Comparer<E> &comp) {
00851         ogdf::quicksortTemplate(*this,comp);
00852     }
00853 
00855     template<class C>
00856     void quicksortCT(C &comp) {
00857         ogdf::quicksortCTTemplate(*this,comp);
00858     }
00859 
00861 
00868     void bucketSort(int l, int h, BucketFunc<E> &f) {
00869         SListPure<E>::bucketSort(l,h,f);
00870     }
00871 
00873     void bucketSort(BucketFunc<E> &f) {
00874         SListPure<E>::bucketSort(f);
00875     }
00876 
00878     void permute() {
00879         SListPure<E>::permute(m_count);
00880     }
00881 
00882     OGDF_NEW_DELETE
00883 }; // class SList
00884 
00885 
00886 
00887 
00888 // sorts list L using bucket sort
00889 // computes l and h value
00890 template<class E>
00891 void SListPure<E>::bucketSort(BucketFunc<E> &f)
00892 {
00893     // if less than two elements, nothing to do
00894     if (m_head == m_tail) return;
00895 
00896     int l, h;
00897     l = h = f.getBucket(m_head->m_x);
00898     
00899     SListElement<E> *pX;
00900     for(pX = m_head->m_next; pX; pX = pX->