Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

HeapT.hh

Go to the documentation of this file.
00001 //=============================================================================
00002 //                                                                            
00003 //                               OpenMesh                                     
00004 //      Copyright (C) 2001-2005 by Computer Graphics Group, RWTH Aachen       
00005 //                           www.openmesh.org                                 
00006 //                                                                            
00007 //-----------------------------------------------------------------------------
00008 //                                                                            
00009 //                                License                                     
00010 //                                                                            
00011 //   This library is free software; you can redistribute it and/or modify it 
00012 //   under the terms of the GNU Library General Public License as published  
00013 //   by the Free Software Foundation, version 2.                             
00014 //                                                                             
00015 //   This library is distributed in the hope that it will be useful, but       
00016 //   WITHOUT ANY WARRANTY; without even the implied warranty of                
00017 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         
00018 //   Library General Public License for more details.                          
00019 //                                                                            
00020 //   You should have received a copy of the GNU Library General Public         
00021 //   License along with this library; if not, write to the Free Software       
00022 //   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 
00023 //                                                                            
00024 //-----------------------------------------------------------------------------
00025 //                                                                            
00026 //   $Revision: 1.3 $
00027 //   $Date: 2005/04/18 09:07:12 $
00028 //                                                                            
00029 //=============================================================================
00030 
00035 //=============================================================================
00036 //
00037 //  CLASS HeapT
00038 //
00039 //=============================================================================
00040 
00041 #ifndef OPENMESH_UTILS_HEAPT_HH
00042 #define OPENMESH_UTILS_HEAPT_HH
00043 
00044 
00045 //== INCLUDES =================================================================
00046 
00047 #include <OpenMesh/Core/System/config.hh>
00048 #include <vector>
00049 #include <OpenMesh/Core/System/omstream.hh>
00050 
00051 //== NAMESPACE ================================================================
00052 
00053 namespace OpenMesh { // BEGIN_NS_OPENMESH
00054 namespace Utils { // BEGIN_NS_UTILS
00055 
00056 //== CLASS DEFINITION =========================================================
00057 
00058 
00067 template <class HeapEntry>
00068 struct HeapInterfaceT
00069 {
00071   bool less(const HeapEntry& _e1, const HeapEntry& _e2);
00072 
00074   bool greater(const HeapEntry& _e1, const HeapEntry& _e2);
00075 
00077   int  get_heap_position(const HeapEntry& _e);
00078 
00080   void set_heap_position(HeapEntry& _e, int _i);
00081 };
00082 
00083 
00084 
00106 template <class HeapEntry, class HeapInterface=HeapEntry>
00107 class HeapT : private std::vector<HeapEntry>
00108 {
00109 public:
00110 
00111   typedef HeapT< HeapEntry, HeapInterface > This;
00112 
00114   HeapT() : HeapVector() {}
00115   
00117   HeapT(const HeapInterface& _interface)
00118     : HeapVector(),  interface_(_interface)
00119   {}
00120   
00122   ~HeapT(){};
00123 
00124 
00126   void clear() { HeapVector::clear(); }
00127 
00129   bool empty() { return HeapVector::empty(); }
00130 
00132   unsigned int size() { return HeapVector::size(); }
00133 
00135   void reserve(unsigned int _n) { HeapVector::reserve(_n); }
00136 
00138   void reset_heap_position(HeapEntry _h)
00139   { interface_.set_heap_position(_h, -1); }
00140   
00142   bool is_stored(HeapEntry _h)
00143   { return interface_.get_heap_position(_h) != -1; }
00144   
00146   void insert(HeapEntry _h)  { push_back(_h); upheap(size()-1); }
00147 
00149   HeapEntry front() { assert(!empty()); return entry(0); }
00150 
00152   void pop_front()
00153   {    
00154     assert(!empty());
00155     interface_.set_heap_position(entry(0), -1);
00156     if (size() > 1)
00157     {
00158       entry(0, entry(size()-1));
00159       resize(size()-1);
00160       downheap(0);
00161     }
00162     else resize(size()-1);
00163   }
00164 
00166   void remove(HeapEntry _h)
00167   {
00168     int pos = interface_.get_heap_position(_h);
00169     interface_.set_heap_position(_h, -1);
00170 
00171     assert(pos != -1);
00172     assert((unsigned int) pos < size());
00173     
00174     // last item ?
00175     if ((unsigned int) pos == size()-1)
00176       resize(size()-1);
00177 
00178     else {
00179       entry(pos, entry(size()-1)); // move last elem to pos
00180       resize(size()-1);
00181       downheap(pos);
00182       upheap(pos);
00183     }
00184   }
00185 
00189   void update(HeapEntry _h)
00190   {
00191     int pos = interface_.get_heap_position(_h);
00192     assert(pos != -1);
00193     assert((unsigned int)pos < size());
00194     downheap(pos);
00195     upheap(pos);
00196   }
00197   
00199   bool check()
00200   {
00201     bool ok(true);
00202     unsigned int i, j;
00203     for (i=0; i<size(); ++i)
00204     {
00205       if (((j=left(i))<size()) && interface_.greater(entry(i), entry(j))) 
00206       {
00207         omerr() << "Heap condition violated\n";
00208         ok=false;
00209       }
00210       if (((j=right(i))<size()) && interface_.greater(entry(i), entry(j)))
00211       {
00212         omerr() << "Heap condition violated\n";
00213         ok=false;
00214       }
00215     }
00216     return ok;
00217   }
00218   
00219   
00220 private:
00221 
00222   // typedef
00223   typedef std::vector<HeapEntry> HeapVector;
00224 
00225   
00227   void upheap(unsigned int _idx);
00228 
00229   
00231   void downheap(unsigned int _idx);
00232 
00233   
00235   inline HeapEntry entry(unsigned int _idx) {
00236     assert(_idx < size());
00237     return (This::operator[](_idx));
00238   }
00239 
00240   
00242   inline void entry(unsigned int _idx, HeapEntry _h) {
00243     assert(_idx < size());
00244     This::operator[](_idx) = _h;
00245     interface_.set_heap_position(_h, _idx);
00246   }
00247 
00248   
00250   inline unsigned int parent(unsigned int _i) { return (_i-1)>>1; }
00252   inline unsigned int left(unsigned int _i)   { return (_i<<1)+1; }
00254   inline unsigned int right(unsigned int _i)  { return (_i<<1)+2; }
00255 
00256 
00258   HeapInterface  interface_;
00259 };
00260 
00261 
00262 
00263 
00264 //== IMPLEMENTATION ========================================================== 
00265 
00266 
00267 template <class HeapEntry, class HeapInterface>
00268 void
00269 HeapT<HeapEntry, HeapInterface>::
00270 upheap(unsigned int _idx)
00271 {
00272   HeapEntry     h = entry(_idx);
00273   unsigned int  parentIdx;
00274 
00275   while ((_idx>0) &&
00276          interface_.less(h, entry(parentIdx=parent(_idx))))
00277   {
00278     entry(_idx, entry(parentIdx));
00279     _idx = parentIdx;    
00280   }
00281   
00282   entry(_idx, h);
00283 }
00284   
00285 
00286 //-----------------------------------------------------------------------------
00287 
00288   
00289 template <class HeapEntry, class HeapInterface>
00290 void
00291 HeapT<HeapEntry, HeapInterface>::
00292 downheap(unsigned int _idx)
00293 {
00294   HeapEntry     h = entry(_idx);
00295   unsigned int  childIdx;
00296   unsigned int  s = size();
00297   
00298   while(_idx < s)
00299   {
00300     childIdx = left(_idx);
00301     if (childIdx >= s) break;
00302     
00303     if ((childIdx+1 < s) &&
00304         (interface_.less(entry(childIdx+1), entry(childIdx))))
00305       ++childIdx;
00306     
00307     if (interface_.less(h, entry(childIdx))) break;
00308 
00309     entry(_idx, entry(childIdx));
00310     _idx = childIdx;
00311   }  
00312 
00313   entry(_idx, h);
00314 }
00315 
00316 
00317 //=============================================================================
00318 } // END_NS_UTILS
00319 } // END_NS_OPENMESH
00320 //=============================================================================
00321 #endif // OSG_HEAP_HH defined
00322 //=============================================================================
00323 

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