Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

/ray/src/lib/tl/tlarrayheap.h

Go to the documentation of this file.
00001 /*
00002  * lib/tl/tlarrayheap.h 
00003  * 
00004  * Complete implementation of heap template (array-based heap). 
00005  * 
00006  * Copyright (c) 2004 by Wolfgang Wieser ] wwieser (a) gmx <*> de [ 
00007  * 
00008  * This file may be distributed and/or modified under the terms of the 
00009  * GNU General Public License version 2 as published by the Free Software 
00010  * Foundation. (See COPYING.GPL for details.)
00011  * 
00012  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014  * 
00015  */
00016 
00017 #ifndef _TemplateLibrary_ArrayHeap_H_
00018 #define _TemplateLibrary_ArrayHeap_H_ 1
00019 
00027 #include <lib/sconfig.h>    /* MUST be first */
00028 
00029 #include <lib/tl/tlarray.h>
00030 
00031 
00062 template<typename T,typename _OP=TLDefaultOperators_CDT<T> >class TLArrayHeap : 
00063     private TLArray<T,_OP>
00064 {
00065     public:
00066         // Access to operator template: 
00067         using TLArray<T,_OP>::OP;
00068         
00069     private:
00070         using TLArray<T,_OP>::nelem;
00071         using TLArray<T,_OP>::asize;
00072         using TLArray<T,_OP>::_free;
00073         using TLArray<T,_OP>::_upsize1;
00074         
00080         inline T &heap(size_t idx)
00081             {  return(TLArray<T,_OP>::array(idx));  }
00082         inline T *heapP(size_t idx)
00083             {  return(TLArray<T,_OP>::arrayP(idx));  }
00084         
00086         void _realloc(size_t new_asize)
00087         {
00088             // Need 1 special extra element: [0]. 
00089             char *new_heap=(char*)OP.realloc(TLArray<T,_OP>::_array,
00090                 (new_asize+1)*OP.size());
00091             TLArray<T,_OP>::_array=new_heap;  asize=new_asize;
00092         }
00094         void _clearall()
00095         {
00096             // NOTE!! This is different in TLArray!!
00097             if(!OP.pdt)  for(size_t i=nelem; i; --i)  OP.clr(heapP(i));
00098             nelem=0;
00099         }
00100         
00102         void _UpHeap(size_t idx)  // internal idx
00103         {
00104             // Store temporary in [0]: 
00105             OP.ini(heapP(0),heap(idx));
00106             while(idx>1 && OP.le(heap(idx/2),heap(0)))
00107             {  OP.ass(heap(idx),heap(idx/2));  idx/=2;  }
00108             OP.ass(heap(idx),heap(0));  OP.clr(heapP(0));
00109         }
00110         
00112         void _DownHeap(size_t idx)  // internal idx
00113         {
00114             size_t j,e=nelem/2;
00115             // Store temporary in [0]: 
00116             OP.ini(heapP(0),heap(idx));
00117             while(idx<=e)
00118             {
00119                 j=idx+idx;
00120                 if(j<nelem && OP.lt(heap(j),heap(j+1)))  ++j;
00121                 if(OP.le(heap(j),heap(0)))  break;
00122                 OP.ass(heap(idx),heap(j));  idx=j;
00123             }
00124             OP.ass(heap(idx),heap(0));  OP.clr(heapP(0));
00125         }
00126         
00129         template<typename K>size_t _RecSearch(const K &key,size_t idx)
00130         {
00131             // Search element in [idx], then in both subtrees (if needed). 
00132             if(OP.eq(heap(idx),key))  return(idx);
00133             idx+=idx;  size_t res=0;  if(idx>nelem)  return(res);
00134             if(OP.ge(heap(idx),key))  res=_RecSearch(key,idx);
00135             if(!res && ++idx<=nelem && OP.ge(heap(idx),key))
00136             {  res=_RecSearch(key,idx);  }
00137             return(res);
00138         }
00139         
00142         template<typename K>inline size_t _LinSearch(const K &key)
00143         {
00144             for(size_t i=1; i<=nelem; i++)
00145                 if(OP.eq(heap(i),key))  return(i);
00146             return(0);
00147         }
00148         
00151         void _ReHeap(size_t /*internal*/idx,int size_change=0)  // internal idx
00152         {
00153             // This implementation could be optimized. 
00155             if(size_change<=0)  _DownHeap(idx);
00156             if(size_change>=0)  _UpHeap(idx);
00157         }
00158         
00160         void _RemoveIdx(size_t idx,T *e=NULL)
00161         {
00162             if(e)  OP.ass(*e,heap(idx));
00163             if(nelem==idx)  {  OP.clr(heapP(nelem--));  return;  }
00164             OP.ass(heap(idx),heap(nelem));  OP.clr(heapP(nelem--));
00165             _ReHeap(idx);
00166         }
00167         
00169         TLArrayHeap(const TLArrayHeap &);
00170         void operator=(const TLArrayHeap &);
00171     public:
00173         TLArrayHeap(const _OP &op=_OP()) : TLArray<T,_OP>(op)  {}
00175         ~TLArrayHeap()
00176             {  _clearall();  _free();   }  // NOTE: OUR version of _clearall()
00177         
00178         #if 0   /* See using directives below. */
00179 
00180         inline bool IsEmpty() const
00181             {  return(TLArray<T,_OP>::IsEmpty());  }
00182         
00184         inline size_t NElem() const
00185             {  return(TLArray<T,_OP>::NElem());  }
00186         #else
00187 
00188         using TLArray<T,_OP>::IsEmpty;
00190         using TLArray<T,_OP>::NElem;
00191         #endif
00192         
00205         inline T &operator[](size_t idx)
00206             {  return(heap(idx+1 /* <-- Correct! */));  }
00207         inline const T &operator[](size_t idx) const
00208             {  return(heap(idx+1 /* <-- Correct! */));  }
00209         
00211         void clear(bool keep_memory=0)
00212         {  _clearall();  TLArray<T,_OP>::clear(keep_memory);  } // OUR version!!
00213         
00217         inline T *first()  {  return(nelem ? heapP(1) : NULL);  }
00218         inline const T *first() const  {  return(nelem ? heapP(1) : NULL);  }
00219         
00221         inline void DownHeapFirst()
00222             {  if(nelem>1) _DownHeap(1);   }
00223         
00236         inline void ReHeap(size_t idx,int size_change=0)
00237             {  if(idx<nelem)  _ReHeap(idx+1,size_change);  }
00238         
00244         void insert(const T &e)
00245             {  _upsize1();  OP.ini(heapP(++nelem),e);  _UpHeap(nelem);  }
00246         
00254         int ReplaceFirst(const T &e)
00255         {
00256             if(!nelem) return(1);
00257             OP.ass(heap(1),e);  _DownHeap(1);  return(0);
00258         }
00259         
00269         int PopFirst(T *e=NULL)
00270         {
00271             if(!nelem)  return(1);
00272             if(e)  OP.ass(*e,heap(1));
00273             if(nelem>1)  OP.ass(heap(1),heap(nelem));
00274             OP.clr(heapP(nelem--));  _DownHeap(1);  return(0);
00275         }
00276         
00287         template<typename K>inline ssize_t LinSearch(const K &key)
00288             {  return((ssize_t)_LinSearch(key)-1);  }
00289         
00307         template<typename K>inline ssize_t RecSearch(const K &key)
00308             {  return(nelem ? ((ssize_t)_RecSearch(key,1))-1 : -1);  }
00309         
00322         template<typename K>int remove(const K &key,T *e=NULL)
00323         {
00324             size_t idx=_LinSearch(key);  if(!idx)  return(1);  // CORRECT
00325             _RemoveIdx(idx,e);  return(0);
00326         }
00327         
00336         int RemoveIdx(size_t idx,T *e=NULL)
00337             {  if(idx>=nelem)  return(1);  _RemoveIdx(idx+1,e);  return(0);  }
00338         
00346         template<typename K>int replace(const K &key,const T &new_ent)
00347         {
00348             size_t idx=_LinSearch(key);  if(!idx)  return(1);  // CORRECT
00349             OP.ass(heap(idx),new_ent);  _ReHeap(idx);  return(0);
00350         }
00351         
00360         int ReplaceIdx(size_t idx,const T &new_ent)
00361         {
00362             if(idx>=nelem)  return(1);  ++idx;
00363             OP.ass(heap(idx),new_ent);  _ReHeap(idx);  return(0);
00364         }
00365         
00370         size_t CheckHeap()
00371         {
00372             size_t nerr=0;
00373             for(size_t i=1; ; i++)
00374             {
00375                 size_t c=i+i;  if(c>nelem)  break;
00376                 if(OP.lt(heap(i),heap(c)))  ++nerr;
00377                 if(++c>nelem)  break;
00378                 if(OP.lt(heap(i),heap(c)))  ++nerr;
00379             }
00380             return(nerr);
00381         }
00382 };
00383 
00384 #endif  /* _TemplateLibrary_ArrayHeap_H_ */

Generated on Sat Feb 19 22:33:46 2005 for Ray by doxygen 1.3.5