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