HeapT.hh
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
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #ifndef ACG_HEAP_HH
00053 #define ACG_HEAP_HH
00054
00055
00056
00057
00058 #include <vector>
00059 #include "../Config/ACGDefines.hh"
00060
00061
00062
00063
00064
00065 namespace ACG {
00066
00067
00068
00069
00070
00079 template <class HeapEntry>
00080 struct HeapInterfaceT
00081 {
00083 bool less(const HeapEntry& _e1, const HeapEntry& _e2);
00084
00086 bool greater(const HeapEntry& _e1, const HeapEntry& _e2);
00087
00089 int get_heap_position(const HeapEntry& _e);
00090
00092 void set_heap_position(HeapEntry& _e, int _i);
00093 };
00094
00095
00096
00113 template <class HeapEntry, class HeapInterface=HeapEntry>
00114 class ACGDLLEXPORT HeapT : private std::vector<HeapEntry>
00115 {
00116 public:
00117
00118 typedef std::vector<HeapEntry> Base;
00119
00120
00122 HeapT() : HeapVector() {}
00123
00125 HeapT(const HeapInterface& _interface)
00126 : HeapVector(), interface_(_interface)
00127 {}
00128
00130 ~HeapT(){};
00131
00132
00134 void clear() { HeapVector::clear(); }
00135
00137 bool empty() { return HeapVector::empty(); }
00138
00140 unsigned int size() { return HeapVector::size(); }
00141
00143 void reserve(unsigned int _n) { HeapVector::reserve(_n); }
00144
00146 void reset_heap_position(HeapEntry _h)
00147 { interface_.set_heap_position(_h, -1); }
00148
00150 bool is_stored(HeapEntry _h)
00151 { return interface_.get_heap_position(_h) != -1; }
00152
00154 void insert(HeapEntry _h) { push_back(_h); upheap(size()-1); }
00155
00157 HeapEntry front() { assert(!empty()); return entry(0); }
00158
00160 void pop_front()
00161 {
00162 assert(!empty());
00163 interface_.set_heap_position(entry(0), -1);
00164 if (size() > 1)
00165 {
00166 entry(0, entry(size()-1));
00167 resize(size()-1);
00168 downheap(0);
00169 }
00170 else resize(size()-1);
00171 }
00172
00174 void remove(HeapEntry _h)
00175 {
00176 int pos = interface_.get_heap_position(_h);
00177 interface_.set_heap_position(_h, -1);
00178
00179 assert(pos != -1);
00180 assert((unsigned int) pos < size());
00181
00182
00183 if ((unsigned int) pos == size()-1)
00184 resize(size()-1);
00185
00186 else {
00187 entry(pos, entry(size()-1));
00188 resize(size()-1);
00189 downheap(pos);
00190 upheap(pos);
00191 }
00192 }
00193
00197 void update(HeapEntry _h)
00198 {
00199 int pos = interface_.get_heap_position(_h);
00200 assert(pos != -1);
00201 assert((unsigned int)pos < size());
00202 downheap(pos);
00203 upheap(pos);
00204 }
00205
00207 bool check()
00208 {
00209 bool ok(true);
00210 unsigned int i, j;
00211 for (i=0; i<size(); ++i)
00212 {
00213 if (((j=left(i))<size()) && interface_.greater(entry(i), entry(j))) {
00214 std::cerr << "Heap condition violated\n";
00215 ok=false;
00216 }
00217 if (((j=right(i))<size()) && interface_.greater(entry(i), entry(j))){
00218 std::cerr << "Heap condition violated\n";
00219 ok=false;
00220 }
00221 }
00222 return ok;
00223 }
00224
00225
00226 private:
00227
00228
00229 typedef std::vector<HeapEntry> HeapVector;
00230
00231
00233 void upheap(unsigned int _idx);
00234
00235
00237 void downheap(unsigned int _idx);
00238
00239
00241 inline HeapEntry entry(unsigned int _idx) {
00242 assert(_idx < size());
00243 return (Base::operator[](_idx));
00244 }
00245
00246
00248 inline void entry(unsigned int _idx, HeapEntry _h) {
00249 assert(_idx < size());
00250 Base::operator[](_idx) = _h;
00251 interface_.set_heap_position(_h, _idx);
00252 }
00253
00254
00256 inline unsigned int parent(unsigned int _i) { return (_i-1)>>1; }
00258 inline unsigned int left(unsigned int _i) { return (_i<<1)+1; }
00260 inline unsigned int right(unsigned int _i) { return (_i<<1)+2; }
00261
00262
00264 HeapInterface interface_;
00265 };
00266
00267
00268
00269
00270
00271
00272
00273 template <class HeapEntry, class HeapInterface>
00274 void
00275 HeapT<HeapEntry, HeapInterface>::
00276 upheap(unsigned int _idx)
00277 {
00278 HeapEntry h = entry(_idx);
00279 unsigned int parentIdx;
00280
00281 while ((_idx>0) &&
00282 interface_.less(h, entry(parentIdx=parent(_idx))))
00283 {
00284 entry(_idx, entry(parentIdx));
00285 _idx = parentIdx;
00286 }
00287
00288 entry(_idx, h);
00289 }
00290
00291
00292
00293
00294
00295 template <class HeapEntry, class HeapInterface>
00296 void
00297 HeapT<HeapEntry, HeapInterface>::
00298 downheap(unsigned int _idx)
00299 {
00300 HeapEntry h = entry(_idx);
00301 unsigned int childIdx;
00302 unsigned int s = size();
00303
00304 while(_idx < s)
00305 {
00306 childIdx = left(_idx);
00307 if (childIdx >= s) break;
00308
00309 if ((childIdx+1 < s) &&
00310 (interface_.less(entry(childIdx+1), entry(childIdx))))
00311 ++childIdx;
00312
00313 if (interface_.less(h, entry(childIdx))) break;
00314
00315 entry(_idx, entry(childIdx));
00316 _idx = childIdx;
00317 }
00318
00319 entry(_idx, h);
00320 }
00321
00322
00323
00324 }
00325
00326 #endif // ACG_HEAP_HH defined
00327
00328