00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00049
00050
00051
00052
00053
00054
00055 #ifndef OPENMESH_UTILS_HEAPT_HH
00056 #define OPENMESH_UTILS_HEAPT_HH
00057
00058
00059
00060
00061 #include "Config.hh"
00062 #include <vector>
00063 #include <OpenMesh/Core/System/omstream.hh>
00064
00065
00066
00067 namespace OpenMesh {
00068 namespace Utils {
00069
00070
00071
00072
00081 template <class HeapEntry>
00082 struct HeapInterfaceT
00083 {
00085 bool less(const HeapEntry& _e1, const HeapEntry& _e2);
00086
00088 bool greater(const HeapEntry& _e1, const HeapEntry& _e2);
00089
00091 int get_heap_position(const HeapEntry& _e);
00092
00094 void set_heap_position(HeapEntry& _e, int _i);
00095 };
00096
00097
00098
00121 template <class HeapEntry, class HeapInterface=HeapEntry>
00122 class HeapT : private std::vector<HeapEntry>
00123 {
00124 private:
00125 typedef std::vector<HeapEntry> Base;
00126
00127 public:
00128
00130 HeapT() : HeapVector() {}
00131
00133 HeapT(const HeapInterface& _interface)
00134 : HeapVector(), interface_(_interface)
00135 {}
00136
00138 ~HeapT(){};
00139
00140
00142 void clear() { HeapVector::clear(); }
00143
00145 bool empty() const { return HeapVector::empty(); }
00146
00148 unsigned int size() const { return HeapVector::size(); }
00149
00151 void reserve(unsigned int _n) { HeapVector::reserve(_n); }
00152
00154 void reset_heap_position(HeapEntry _h)
00155 { interface_.set_heap_position(_h, -1); }
00156
00158 bool is_stored(HeapEntry _h)
00159 { return interface_.get_heap_position(_h) != -1; }
00160
00162 void insert(HeapEntry _h)
00163 {
00164 push_back(_h);
00165 upheap(size()-1);
00166 }
00167
00169 HeapEntry front() const
00170 {
00171 assert(!empty());
00172 return entry(0);
00173 }
00174
00176 void pop_front()
00177 {
00178 assert(!empty());
00179 reset_heap_position(entry(0));
00180 if (size() > 1)
00181 {
00182 entry(0, entry(size()-1));
00183 Base::pop_back();
00184 downheap(0);
00185 }
00186 else
00187 {
00188 Base::pop_back();
00189 }
00190 }
00191
00193 void remove(HeapEntry _h)
00194 {
00195 int pos = interface_.get_heap_position(_h);
00196 reset_heap_position(_h);
00197
00198 assert(pos != -1);
00199 assert((unsigned int) pos < size());
00200
00201
00202 if ((unsigned int) pos == size()-1)
00203 {
00204 Base::pop_back();
00205 }
00206 else
00207 {
00208 entry(pos, entry(size()-1));
00209 Base::pop_back();
00210 downheap(pos);
00211 upheap(pos);
00212 }
00213 }
00214
00218 void update(HeapEntry _h)
00219 {
00220 int pos = interface_.get_heap_position(_h);
00221 assert(pos != -1);
00222 assert((unsigned int)pos < size());
00223 downheap(pos);
00224 upheap(pos);
00225 }
00226
00228 bool check()
00229 {
00230 bool ok(true);
00231 unsigned int i, j;
00232 for (i=0; i<size(); ++i)
00233 {
00234 if (((j=left(i))<size()) && interface_.greater(entry(i), entry(j)))
00235 {
00236 omerr() << "Heap condition violated\n";
00237 ok=false;
00238 }
00239 if (((j=right(i))<size()) && interface_.greater(entry(i), entry(j)))
00240 {
00241 omerr() << "Heap condition violated\n";
00242 ok=false;
00243 }
00244 }
00245 return ok;
00246 }
00247
00248 protected:
00250 HeapInterface interface_;
00251
00252 private:
00253
00254 typedef std::vector<HeapEntry> HeapVector;
00255
00256
00258 void upheap(unsigned int _idx);
00259
00260
00262 void downheap(unsigned int _idx);
00263
00264
00266 inline HeapEntry entry(unsigned int _idx) const
00267 {
00268 assert(_idx < size());
00269 return (Base::operator[](_idx));
00270 }
00271
00272
00274 inline void entry(unsigned int _idx, HeapEntry _h)
00275 {
00276 assert(_idx < size());
00277 Base::operator[](_idx) = _h;
00278 interface_.set_heap_position(_h, _idx);
00279 }
00280
00281
00283 inline unsigned int parent(unsigned int _i) { return (_i-1)>>1; }
00285 inline unsigned int left(unsigned int _i) { return (_i<<1)+1; }
00287 inline unsigned int right(unsigned int _i) { return (_i<<1)+2; }
00288
00289 };
00290
00291
00292
00293
00294
00295
00296
00297 template <class HeapEntry, class HeapInterface>
00298 void
00299 HeapT<HeapEntry, HeapInterface>::
00300 upheap(unsigned int _idx)
00301 {
00302 HeapEntry h = entry(_idx);
00303 unsigned int parentIdx;
00304
00305 while ((_idx>0) &&
00306 interface_.less(h, entry(parentIdx=parent(_idx))))
00307 {
00308 entry(_idx, entry(parentIdx));
00309 _idx = parentIdx;
00310 }
00311
00312 entry(_idx, h);
00313 }
00314
00315
00316
00317
00318
00319 template <class HeapEntry, class HeapInterface>
00320 void
00321 HeapT<HeapEntry, HeapInterface>::
00322 downheap(unsigned int _idx)
00323 {
00324 HeapEntry h = entry(_idx);
00325 unsigned int childIdx;
00326 unsigned int s = size();
00327
00328 while(_idx < s)
00329 {
00330 childIdx = left(_idx);
00331 if (childIdx >= s) break;
00332
00333 if ((childIdx+1 < s) &&
00334 (interface_.less(entry(childIdx+1), entry(childIdx))))
00335 ++childIdx;
00336
00337 if (interface_.less(h, entry(childIdx))) break;
00338
00339 entry(_idx, entry(childIdx));
00340 _idx = childIdx;
00341 }
00342
00343 entry(_idx, h);
00344 }
00345
00346
00347
00348 }
00349 }
00350
00351 #endif // OSG_HEAP_HH defined
00352
00353