MeVisLabToolboxReference
MeVisLab/Standard/Sources/ML/MLWEM/WEMDataStructure/WEMHeap.h
Go to the documentation of this file.
00001 // **InsertLicense** code
00002 //----------------------------------------------------------------------------------
00007 
00015 #ifndef __WEMHeap_H
00016 #define __WEMHeap_H
00017 
00018 #include "WEMVector.h"
00019 #include "WEMBase/WEMPrimitive.h"
00020 
00021 
00022 ML_START_NAMESPACE
00023 
00025 
00030 template <class T>
00031 class WEMHeap : public WEMVector<WEMPrimitive> 
00032 {
00033 public:
00034 
00036   WEMHeap();
00038   ~WEMHeap();
00040   T* root();
00042   const T* root() const;
00044   void swap(unsigned int i,unsigned int j);
00046   void insert(WEMPrimitive *wp);
00048   void insert(WEMPrimitive *wp, double v);
00050   void update(WEMPrimitive *wp, double nv);
00052   int remove(WEMPrimitive *wp);
00054   void sort();
00055 
00056 private:
00057 
00059   inline int parent(int i) const {return (i-1)/2;}
00061   inline int left(int i)   const {return 2*i+1;}
00063   inline int right(int i)  const {return 2*i+2;}
00065   int upHeap(int i);
00067   int downHeap(int i);
00068 };
00069 
00072 
00073 template <class T>
00074 WEMHeap<T>::WEMHeap() : WEMVector<WEMPrimitive>()
00075 {
00076 }
00077 
00079 
00080 template <class T>
00081 WEMHeap<T>::~WEMHeap()
00082 {
00083   clear();
00084 }
00085 
00087 
00088 template <class T>
00089 T* WEMHeap<T>::root()
00090 {
00091   WEMPrimitive *wp = WEMVector<WEMPrimitive>::first();
00092   if (wp) 
00093   {
00094     return reinterpret_cast<T*>(wp);
00095   } 
00096   else 
00097   {
00098     return NULL;
00099   }
00100 }
00101 
00103 
00104 template <class T>
00105 const T* WEMHeap<T>::root() const
00106 {
00107   return root();
00108 }
00109 
00111 
00112 template <class T>
00113 void WEMHeap<T>::swap(unsigned int i,unsigned int j) 
00114 {
00115   WEMVector<WEMPrimitive>::swap(i,j);
00116   at(i)->setHeapPosition(i);
00117   at(j)->setHeapPosition(j);
00118 }
00119 
00121 
00122 template <class T>
00123 void WEMHeap<T>::insert(WEMPrimitive *wp)
00124 {
00125   if (wp == NULL)                  { return; }
00126   if (wp->getHeapPosition() != -1) { return; }
00127 
00128   WEMVector<WEMPrimitive>::appendUnsafe(wp);
00129   const unsigned int n = num()-1;
00130   last()->setHeapPosition(n);
00131   upHeap(n);
00132 }
00133 
00135 
00136 template <class T>
00137 void WEMHeap<T>::insert(WEMPrimitive *wp,double v)
00138 {
00139   if (wp == NULL) { return; }
00140 
00141   if (wp->getHeapPosition() == -1) 
00142   {
00143     wp->setHeapValue(v);
00144     WEMVector<WEMPrimitive>::appendUnsafe(wp);
00145     const unsigned int n = num()-1;
00146     last()->setHeapPosition(n);
00147     upHeap(n);
00148   } 
00149   else 
00150   {
00151     update(wp,v);
00152   }
00153 }
00154 
00156 
00157 template <class T>
00158 int WEMHeap<T>::remove(WEMPrimitive *wp)
00159 {
00160   if (wp == NULL) { return -1; }
00161 
00162   const int i = wp->getHeapPosition();
00163   if (i == -1) { return -1; }
00164 
00165   const int n = num();
00166   if (i >= n) { return -1; }
00167 
00168   if (i != n - 1)
00169   {
00170     swap(i,n - 1);
00171     at(n - 1)->setHeapPosition(-1);
00172     deleteLast();
00173     if (at(i)->getHeapValue() < wp->getHeapValue()) 
00174     {
00175       return upHeap(i);
00176     } 
00177     else 
00178     {
00179       return downHeap(i);
00180     }
00181   } 
00182   else 
00183   {
00184     at(n - 1)->setHeapPosition(-1);
00185     deleteLast();
00186   }
00187   return -1;
00188 }
00189 
00191 
00192 template <class T>
00193 void WEMHeap<T>::update(WEMPrimitive *wp,double nv)
00194 {
00195   const int i = wp->getHeapPosition();
00196   if (i == -1) { return; }
00197 
00198   const int n = num();
00199   if (i >= n) { return; }
00200 
00201   const double ov = wp->getHeapValue();
00202 
00203   wp->setHeapValue(nv);
00204 
00205   if (nv < ov) 
00206   { 
00207     upHeap(i); 
00208   } 
00209   else 
00210   {
00211     downHeap(i);
00212   }
00213 }
00214 
00216 
00217 template <class T>
00218 int WEMHeap<T>::upHeap(int i)
00219 {
00220   if (i == 0) { return 0; }
00221   const int pi = parent(i);
00222   if (at(i)->getHeapValue() < at(pi)->getHeapValue()) 
00223   {
00224     swap(i,pi);
00225     return upHeap(pi);
00226   }
00227   return i;
00228 }
00229 
00231 
00232 template <class T>
00233 int WEMHeap<T>::downHeap(int i)
00234 {
00235   int largest=i,l=left(i),r=right(i);
00236   const int n = num();
00237 
00238   if (i >= n) { return -1; }
00239   if ((l < n) && (at(l)->getHeapValue() < at(largest)->getHeapValue())) { largest=l; }
00240   if ((r < n) && (at(r)->getHeapValue() < at(largest)->getHeapValue())) { largest=r; }
00241 
00242   if (largest !=i ) 
00243   {
00244     swap(i,largest);
00245     return downHeap(largest);
00246   }
00247   return i;
00248 }
00249 
00251 
00252 template <class T>
00253 void WEMHeap<T>::sort()
00254 {
00255   WEMVector<WEMPrimitive> *newheap = NULL;
00256   ML_CHECK_NEW(newheap, WEMVector<WEMPrimitive>());
00257 
00258   unsigned int i = 0;
00259   const unsigned int n = num();
00260   for (i = 0; i < n; i ++) { newheap->append(at(i)); }
00261   clear();
00262   const unsigned int nn = newheap->num();
00263   for (i = 0; i < nn; i ++) { insert(newheap->at(i)); }
00264   ML_DELETE(newheap);
00265 }
00266 
00269 
00270 ML_END_NAMESPACE
00271 
00272 #endif // __WEMHEAP_H__