00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _TemplateLibrary_LinkedList_H_
00019 #define _TemplateLibrary_LinkedList_H_ 1
00020
00094 #include <lib/sconfig.h>
00095
00096
00102 template<typename T> struct LinkedListBase
00103 {
00104 T *prev,*next;
00105
00106 enum _LLB_NoInit { LLB_NoInit };
00107
00109 inline LinkedListBase() { prev=next=NULL; }
00111 inline LinkedListBase(_LLB_NoInit) { }
00113 inline ~LinkedListBase() { }
00114 };
00115
00116
00117
00118 #define _LLB LinkedListBase<T>
00119
00126 template<typename T> class LinkedList
00127 {
00128 private:
00129 T *lfirst,*llast;
00130
00132 inline LinkedList &operator=(const LinkedList &l)
00133 { lfirst=l.lfirst; llast=l.llast; return(*this); }
00134 inline LinkedList(const LinkedList &l)
00135 { lfirst=l.lfirst; llast=l.llast; }
00136 public:
00138 inline LinkedList() { lfirst=llast=NULL; }
00141 inline ~LinkedList() { }
00142
00144 inline T *first() const { return(lfirst); }
00145 inline T *last() const { return(llast); }
00146
00148 inline bool IsEmpty() const { return(!lfirst); }
00149
00153 inline T *next(T *p) const { return(p->_LLB::next); }
00154 inline T *prev(T *p) const { return(p->_LLB::prev); }
00155 inline const T *next(const T *p) const { return(p->_LLB::next); }
00156 inline const T *prev(const T *p) const { return(p->_LLB::prev); }
00157
00161 inline void AssignList(const LinkedList<T> *l)
00162 { lfirst=l->lfirst; llast=l->llast; }
00163
00165 inline void SwapList(LinkedList<T> *l)
00166 { T *tmp=lfirst; lfirst=l->lfirst; l->lfirst=tmp;
00167 tmp=llast; llast= l->llast; l->llast= tmp; }
00168
00170 inline void insert(T *p)
00171 {
00172 if(!p) return;
00173 p->_LLB::next=lfirst;
00174 p->_LLB::prev=NULL;
00175
00176
00177 (lfirst ? lfirst->_LLB::prev : llast)=p;
00178 lfirst=p;
00179 }
00180
00182 inline void append(T *p)
00183 {
00184 if(!p) return;
00185 p->_LLB::prev=llast;
00186 p->_LLB::next=NULL;
00187
00188
00189 (llast ? llast->_LLB::next : lfirst)=p;
00190 llast=p;
00191 }
00192
00196 inline T *replace(T *newp,T *oldp)
00197 {
00198 newp->_LLB::next=oldp->_LLB::next;
00199 newp->_LLB::prev=oldp->_LLB::prev;
00200 if(lfirst==oldp) lfirst=newp;
00201 if(llast==oldp) llast=newp;
00202 oldp->_LLB::prev=oldp->_LLB::next=NULL;
00203 return(oldp);
00204 }
00205
00208 inline void QueueBefore(T *p,T *where)
00209 {
00210 if(!p) return;
00211 if(where==lfirst)
00212 { insert(p); return; }
00213 p->_LLB::prev=where->_LLB::prev;
00214 where->_LLB::prev->_LLB::next=p;
00215 where->_LLB::prev=p;
00216 p->_LLB::next=where;
00217 }
00218 inline void QueueAfter(T *p,T *where)
00219 {
00220 if(!p) return;
00221 if(where==llast)
00222 { append(p); return; }
00223 p->_LLB::next=where->_LLB::next;
00224 where->_LLB::next->_LLB::prev=p;
00225 where->_LLB::next=p;
00226 p->_LLB::prev=where;
00227 }
00228
00231 void queue(T *p,T *where,int loc)
00232 {
00233 if(loc<0) QueueBefore(p,where);
00234 if(loc>0) QueueAfter(p,where);
00235 }
00236
00238 inline T *dequeue(T *p)
00239 {
00240 if(!p) return(p);
00241 if(p==lfirst) lfirst=lfirst->_LLB::next;
00242 else p->_LLB::prev->_LLB::next=p->_LLB::next;
00243 if(p==llast) llast=llast->_LLB::prev;
00244 else p->_LLB::next->_LLB::prev=p->_LLB::prev;
00245 p->_LLB::next=p->_LLB::prev=NULL;
00246 return(p);
00247 }
00248
00250 inline T *PopFirst()
00251 {
00252 if(!lfirst) return(lfirst);
00253 T *p=lfirst;
00254 lfirst=lfirst->_LLB::next;
00255 if(lfirst) lfirst->_LLB::prev=NULL;
00256 else llast=NULL;
00257 p->_LLB::next=NULL;
00258 return(p);
00259 }
00260 inline T *PopLast()
00261 {
00262 if(!llast) return(llast);
00263 T *p=llast;
00264 llast=llast->_LLB::prev;
00265 if(llast) llast->_LLB::next=NULL;
00266 else lfirst=NULL;
00267 p->_LLB::prev=NULL;
00268 return(p);
00269 }
00270
00272 inline const T *search(const T *p) const
00273 {
00274 for(T *i=lfirst; i; i=i->_LLB::next)
00275 { if(i==p) return(p); }
00276 return(NULL);
00277 }
00279 inline const T *SearchRev(const T *p) const
00280 {
00281 for(T *i=llast; i; i=i->_LLB::prev)
00282 { if(i==p) return(p); }
00283 return(NULL);
00284 }
00285
00287 inline int count() const
00288 {
00289 int cnt=0;
00290 for(T *i=lfirst; i; i=i->_LLB::next,cnt++);
00291 return(cnt);
00292 }
00293
00295 inline void clear()
00296 { while(!IsEmpty()) delete PopFirst(); }
00297
00310 inline void AppendList(LinkedList<T> &b)
00311 {
00312 if(b.IsEmpty()) return;
00313
00314 b.lfirst->prev=llast;
00315
00316
00317 (llast ? llast->_LLB::next : lfirst)=b.lfirst;
00318 llast=b.llast;
00319
00320 b.lfirst=NULL; b.llast=NULL;
00321 }
00322
00342 inline T *MiddleNode() const
00343 {
00344
00345 T *a=lfirst;
00346 for(T *b=llast; a!=b; b=b->_LLB::prev) if((a=a->next)==b) break;
00347 return(a);
00348 }
00349
00368 template<typename OP>void MergeLists(
00369 LinkedList<T> &a,LinkedList<T> &b,const OP &_OP)
00370 {
00371 for(;;)
00372 {
00373 T *af=a.lfirst; if(!af) { AppendList(b); break; }
00374 T *bf=b.lfirst; if(!bf) { AppendList(a); break; }
00375 if(_OP.le(*af,*bf)) append(a.PopFirst());
00376 else append(b.PopFirst());
00377 }
00378 }
00379
00391 template<typename OP>void MergeSort(const OP &_OP)
00392 {
00393 if(IsEmpty()) return;
00396
00397 T *m=MiddleNode();
00398 LinkedList<T> a,b;
00399 a.lfirst=lfirst; a.llast=m; m->_LLB::next=NULL; lfirst=NULL;
00400 b.lfirst=m; b.llast=llast; m->_LLB::prev=NULL; llast=NULL;
00401
00402 a.MergeSort(_OP); b.MergeSort(_OP);
00403
00404 MergeLists(a,b,_OP);
00405 }
00406 };
00407
00408 #undef _LLB
00409
00410 #endif