MeVisLabToolboxReference
MeVisLab/Standard/Sources/ML/MLCSO/CSOTools/CSOObjectHeap.h
Go to the documentation of this file.
00001 // **InsertLicense** code
00002 //----------------------------------------------------------------------------------
00004 
00009 //----------------------------------------------------------------------------------
00010 
00011 
00012 #ifndef __CSOObjectHeap_H
00013 #define __CSOObjectHeap_H
00014 
00015 #include "CSOObjectVector.h"
00016 
00017 
00018 ML_START_NAMESPACE
00019 
00021 
00026 template <class T>
00027 class CSOObjectHeap : public CSOObjectVector<T> 
00028 {
00029 
00030 public:
00031 
00033   CSOObjectHeap();
00035   ~CSOObjectHeap();
00037   T* root() const;
00039   void swap(unsigned int i,unsigned int j);
00041   void insert(T *we);
00043   void insert(T *we,float v);
00045   void update(T *we,float nv);
00047   int remove(T *we);
00049   void sort();
00050 
00051 private:
00052 
00054   inline int parent(int i) const {return (i-1)/2;}
00056   inline int left(int i) const {return 2*i+1;}
00058   inline int right(int i) const {return 2*i+2;}
00060   int upHeap(int i);
00062   int downHeap(int i);
00063 };
00064 
00067 
00068 template <class T>
00069 CSOObjectHeap<T>::CSOObjectHeap() : CSOObjectVector<T>()
00070 { 
00071 }
00072 
00074 
00075 template <class T>
00076 CSOObjectHeap<T>::~CSOObjectHeap()
00077 {
00078   CSOObjectVector<T>::clear();
00079 }
00080 
00082 
00083 template <class T>
00084 T* CSOObjectHeap<T>::root() const
00085 {
00086   return static_cast<T*>(CSOObjectVector<T>::firstBoundsCheck());
00087 }
00088 
00090 
00091 template <class T>
00092 void CSOObjectHeap<T>::swap(unsigned int i,unsigned int j)
00093 {
00094   CSOObjectVector<T>::swap(i,j);
00095   CSOObjectVector<T>::at(i)->heapPosition = i;
00096   CSOObjectVector<T>::at(j)->heapPosition = j;
00097 }
00098 
00100 
00101 template <class T>
00102 void CSOObjectHeap<T>::insert(T *we)
00103 {
00104   if (we==NULL)               { return; }
00105   if (we->heapPosition != -1) { return; }
00106 
00107   CSOObjectVector<T>::appendUnsafe(we);
00108   const int n = (int)CSOObjectVector<T>::num()-1;
00109   CSOObjectVector<T>::last()->heapPosition = n;
00110   upHeap(n);
00111 }
00112 
00114 
00115 template <class T>
00116 void CSOObjectHeap<T>::insert(T *we,float v)
00117 {
00118   if (we==NULL) { return; }
00119 
00120   if (we->heapPosition == -1) 
00121   {
00122     we->value = v;
00123     CSOObjectVector<T>::appendUnsafe(we);
00124     CSOObjectVector<T>::last()->heapPosition = CSOObjectVector<T>::num()-1;
00125     upHeap(CSOObjectVector<T>::num()-1);
00126   } 
00127   else 
00128   {
00129     update(we,v);
00130   }
00131 }
00132 
00134 
00135 template <class T>
00136 int CSOObjectHeap<T>::remove(T *we)
00137 {
00138   if (we == NULL) { return -1; }
00139 
00140   const int i = we->heapPosition;
00141   if (i == -1) { return -1; }
00142 
00143   const int n = CSOObjectVector<T>::num();
00144   if (i >= n) { return -1; }
00145 
00146   if (i != n - 1) 
00147   {
00148     swap(i,n - 1);
00149     CSOObjectVector<T>::at(n - 1)->heapPosition = -1;
00150     CSOObjectVector<T>::deleteLast();
00151     if (CSOObjectVector<T>::at(i)->value < we->value) 
00152     {
00153       return upHeap(i);
00154     } 
00155     else 
00156     {
00157       return downHeap(i);
00158     }
00159   } 
00160   else 
00161   {
00162     CSOObjectVector<T>::at(n - 1)->heapPosition = -1;
00163     CSOObjectVector<T>::deleteLast();
00164   }
00165   return -1;
00166 }
00167 
00169 
00170 template <class T>
00171 void CSOObjectHeap<T>::update(T *we,float nv)
00172 {
00173   const int i = we->heapPosition;
00174   if (i == -1) { return; }
00175 
00176   const int n = CSOObjectVector<T>::num();
00177   if (i >= n) { return; }
00178 
00179   const float ov = static_cast<float>(we->value);
00180 
00181   we->value = nv;
00182 
00183   if (nv < ov) 
00184   {
00185     upHeap(i);
00186   } 
00187   else 
00188   {
00189     downHeap(i);
00190   }
00191 }
00192 
00194 
00195 template <class T>
00196 int CSOObjectHeap<T>::upHeap(int i)
00197 {
00198   if (i==0) { return 0; }
00199   const int pi = parent(i);
00200   if (CSOObjectVector<T>::at(i)->value < CSOObjectVector<T>::at(pi)->value) 
00201   {
00202     swap(i,pi);
00203     return upHeap(pi);
00204   }
00205   return i;
00206 }
00207 
00209 
00210 template <class T>
00211 int CSOObjectHeap<T>::downHeap(int i)
00212 {
00213   int largest=i,l=left(i),r=right(i);
00214   const int n = CSOObjectVector<T>::num();
00215 
00216   if (i >= n) { return -1; }
00217   if ((l < n) && (CSOObjectVector<T>::at(l)->value < CSOObjectVector<T>::at(largest)->value)) { largest=l; }
00218   if ((r < n) && (CSOObjectVector<T>::at(r)->value < CSOObjectVector<T>::at(largest)->value)) { largest=r; }
00219 
00220   if (largest!=i)
00221   {
00222     swap(i,largest);
00223     return downHeap(largest);
00224   }
00225   return i;
00226 }
00227 
00229 
00230 template <class T>
00231 void CSOObjectHeap<T>::sort()
00232 {
00233   CSOObjectVector<T> *newheap = NULL;
00234   ML_CHECK_NEW(newheap, CSOObjectVector<T>());
00235 
00236   unsigned int i=0;
00237   unsigned int n = CSOObjectVector<T>::num();
00238   for (i = 0; i < n; ++i) 
00239   {
00240     newheap->append(CSOObjectVector<T>::at(i)); 
00241   }
00242   CSOObjectVector<T>::clear();
00243   n = newheap->CSOObjectVector<T>::num();
00244   for ( i = 0; i < n; ++i)
00245   { 
00246     insert(newheap->CSOObjectVector<T>::at(i)); 
00247   }
00248   ML_DELETE(newheap);
00249 }
00250 
00252 
00253 
00254 ML_END_NAMESPACE
00255 
00256 #endif // __CSOObjectHeap_H