HeapT.hh

00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                              OpenFlipper                                  *
00004  *      Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen      *
00005  *                           www.openflipper.org                             *
00006  *                                                                           *
00007  *---------------------------------------------------------------------------*
00008  *  This file is part of OpenFlipper.                                        *
00009  *                                                                           *
00010  *  OpenFlipper is free software: you can redistribute it and/or modify      *
00011  *  it under the terms of the GNU Lesser General Public License as           *
00012  *  published by the Free Software Foundation, either version 3 of           *
00013  *  the License, or (at your option) any later version with the              *
00014  *  following exceptions:                                                    *
00015  *                                                                           *
00016  *  If other files instantiate templates or use macros                       *
00017  *  or inline functions from this file, or you compile this file and         *
00018  *  link it with other files to produce an executable, this file does        *
00019  *  not by itself cause the resulting executable to be covered by the        *
00020  *  GNU Lesser General Public License. This exception does not however       *
00021  *  invalidate any other reasons why the executable file might be            *
00022  *  covered by the GNU Lesser General Public License.                        *
00023  *                                                                           *
00024  *  OpenFlipper is distributed in the hope that it will be useful,           *
00025  *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00026  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
00027  *  GNU Lesser General Public License for more details.                      *
00028  *                                                                           *
00029  *  You should have received a copy of the GNU LesserGeneral Public          *
00030  *  License along with OpenFlipper. If not,                                  *
00031  *  see <http://www.gnu.org/licenses/>.                                      *
00032  *                                                                           *
00033 \*===========================================================================*/
00034 
00035 /*===========================================================================*\
00036  *                                                                           *
00037  *   $Revision: 8521 $                                                       *
00038  *   $Author: moebius $                                                      *
00039  *   $Date: 2010-02-10 15:57:35 +0100 (Mi, 10. Feb 2010) $                   *
00040  *                                                                           *
00041 \*===========================================================================*/
00042 
00043 
00044 
00045 
00046 //=============================================================================
00047 //
00048 //  CLASS HeapT
00049 //
00050 //=============================================================================
00051 
00052 #ifndef ACG_HEAP_HH
00053 #define ACG_HEAP_HH
00054 
00055 
00056 //== INCLUDES =================================================================
00057 
00058 #include <vector>
00059 #include "../Config/ACGDefines.hh"
00060 
00061 
00062 //== NAMESPACE ================================================================
00063 
00064 
00065 namespace ACG {
00066 
00067 
00068 //== CLASS DEFINITION =========================================================
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     // last item ?
00183     if ((unsigned int) pos == size()-1)
00184       resize(size()-1);
00185 
00186     else {
00187       entry(pos, entry(size()-1)); // move last elem to pos
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   // typedef
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 //== IMPLEMENTATION ==========================================================
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 } // namespace ACG
00325 //=============================================================================
00326 #endif // ACG_HEAP_HH defined
00327 //=============================================================================
00328 

acg pic Project OpenFlipper, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .