MeVisLabToolboxReference
|
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