Go to the documentation of this file.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
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00060
00061
00062
00063
00064
00065
00066 #ifndef OPENMESH_UTILS_HEAPT_HH
00067 #define OPENMESH_UTILS_HEAPT_HH
00068
00069
00070
00071
00072 #include "Config.hh"
00073 #include <vector>
00074 #include <OpenMesh/Core/System/omstream.hh>
00075
00076
00077
00078 namespace OpenMesh {
00079 namespace Utils {
00080
00081
00082
00083
00092 template <class HeapEntry>
00093 struct HeapInterfaceT
00094 {
00096 bool less(const HeapEntry& _e1, const HeapEntry& _e2);
00097
00099 bool greater(const HeapEntry& _e1, const HeapEntry& _e2);
00100
00102 int get_heap_position(const HeapEntry& _e);
00103
00105 void set_heap_position(HeapEntry& _e, int _i);
00106 };
00107
00108
00109
00132 template <class HeapEntry, class HeapInterface=HeapEntry>
00133 class HeapT : private std::vector<HeapEntry>
00134 {
00135 private:
00136 typedef std::vector<HeapEntry> Base;
00137
00138 public:
00139
00141 HeapT() : HeapVector() {}
00142
00144 HeapT(const HeapInterface& _interface)
00145 : HeapVector(), interface_(_interface)
00146 {}
00147
00149 ~HeapT(){};
00150
00151
00153 void clear() { HeapVector::clear(); }
00154
00156 bool empty() const { return HeapVector::empty(); }
00157
00159 unsigned int size() const { return HeapVector::size(); }
00160
00162 void reserve(unsigned int _n) { HeapVector::reserve(_n); }
00163
00165 void reset_heap_position(HeapEntry _h)
00166 { interface_.set_heap_position(_h, -1); }
00167
00169 bool is_stored(HeapEntry _h)
00170 { return interface_.get_heap_position(_h) != -1; }
00171
00173 void insert(HeapEntry _h)
00174 {
00175 push_back(_h);
00176 upheap(size()-1);
00177 }
00178
00180 HeapEntry front() const
00181 {
00182 assert(!empty());
00183 return entry(0);
00184 }
00185
00187 void pop_front()
00188 {
00189 assert(!empty());
00190 reset_heap_position(entry(0));
00191 if (size() > 1)
00192 {
00193 entry(0, entry(size()-1));
00194 Base::pop_back();
00195 downheap(0);
00196 }
00197 else
00198 {
00199 Base::pop_back();
00200 }
00201 }
00202
00204 void remove(HeapEntry _h)
00205 {
00206 int pos = interface_.get_heap_position(_h);
00207 reset_heap_position(_h);
00208
00209 assert(pos != -1);
00210 assert((unsigned int) pos < size());
00211
00212
00213 if ((unsigned int) pos == size()-1)
00214 {
00215 Base::pop_back();
00216 }
00217 else
00218 {
00219 entry(pos, entry(size()-1));
00220 Base::pop_back();
00221 downheap(pos);
00222 upheap(pos);
00223 }
00224 }
00225
00229 void update(HeapEntry _h)
00230 {
00231 int pos = interface_.get_heap_position(_h);
00232 assert(pos != -1);
00233 assert((unsigned int)pos < size());
00234 downheap(pos);
00235 upheap(pos);
00236 }
00237
00239 bool check()
00240 {
00241 bool ok(true);
00242 unsigned int i, j;
00243 for (i=0; i<size(); ++i)
00244 {
00245 if (((j=left(i))<size()) && interface_.greater(entry(i), entry(j)))
00246 {
00247 omerr() << "Heap condition violated\n";
00248 ok=false;
00249 }
00250 if (((j=right(i))<size()) && interface_.greater(entry(i), entry(j)))
00251 {
00252 omerr() << "Heap condition violated\n";
00253 ok=false;
00254 }
00255 }
00256 return ok;
00257 }
00258
00259 protected:
00261 HeapInterface interface_;
00262
00263 private:
00264
00265 typedef std::vector<HeapEntry> HeapVector;
00266
00267
00269 void upheap(unsigned int _idx);
00270
00271
00273 void downheap(unsigned int _idx);
00274
00275
00277 inline HeapEntry entry(unsigned int _idx) const
00278 {
00279 assert(_idx < size());
00280 return (Base::operator[](_idx));
00281 }
00282
00283
00285 inline void entry(unsigned int _idx, HeapEntry _h)
00286 {
00287 assert(_idx < size());
00288 Base::operator[](_idx) = _h;
00289 interface_.set_heap_position(_h, _idx);
00290 }
00291
00292
00294 inline unsigned int parent(unsigned int _i) { return (_i-1)>>1; }
00296 inline unsigned int left(unsigned int _i) { return (_i<<1)+1; }
00298 inline unsigned int right(unsigned int _i) { return (_i<<1)+2; }
00299
00300 };
00301
00302
00303
00304
00305
00306
00307
00308 template <class HeapEntry, class HeapInterface>
00309 void
00310 HeapT<HeapEntry, HeapInterface>::
00311 upheap(unsigned int _idx)
00312 {
00313 HeapEntry h = entry(_idx);
00314 unsigned int parentIdx;
00315
00316 while ((_idx>0) &&
00317 interface_.less(h, entry(parentIdx=parent(_idx))))
00318 {
00319 entry(_idx, entry(parentIdx));
00320 _idx = parentIdx;
00321 }
00322
00323 entry(_idx, h);
00324 }
00325
00326
00327
00328
00329
00330 template <class HeapEntry, class HeapInterface>
00331 void
00332 HeapT<HeapEntry, HeapInterface>::
00333 downheap(unsigned int _idx)
00334 {
00335 HeapEntry h = entry(_idx);
00336 unsigned int childIdx;
00337 unsigned int s = size();
00338
00339 while(_idx < s)
00340 {
00341 childIdx = left(_idx);
00342 if (childIdx >= s) break;
00343
00344 if ((childIdx+1 < s) &&
00345 (interface_.less(entry(childIdx+1), entry(childIdx))))
00346 ++childIdx;
00347
00348 if (interface_.less(h, entry(childIdx))) break;
00349
00350 entry(_idx, entry(childIdx));
00351 _idx = childIdx;
00352 }
00353
00354 entry(_idx, h);
00355 }
00356
00357
00358
00359 }
00360 }
00361
00362 #endif // OSG_HEAP_HH defined
00363
00364