00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _TemplateLibrary_ArrayHeap_H_
00018 #define _TemplateLibrary_ArrayHeap_H_ 1
00019
00027 #include <lib/sconfig.h>
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
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
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
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)
00103 {
00104
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)
00113 {
00114 size_t j,e=nelem/2;
00115
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
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 idx,int size_change=0)
00152 {
00153
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(); }
00177
00178 #if 0
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 )); }
00207 inline const T &operator[](size_t idx) const
00208 { return(heap(idx+1 )); }
00209
00211 void clear(bool keep_memory=0)
00212 { _clearall(); TLArray<T,_OP>::clear(keep_memory); }
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);
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);
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