Blender V2.61 - r43446

CTR_UHeap.h

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): none yet.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00047 #ifndef NAN_INCLUDED_CTR_UHeap_h
00048 #define NAN_INCLUDED_CTR_UHeap_h
00049 
00050 #include <vector>
00051 
00052 #include "MEM_NonCopyable.h"
00053 
00054 class CTR_UHeapable {
00055 
00056 public :
00057         int &
00058     HeapPos(
00059     ){
00060         return m_ind;
00061     };
00062         float &
00063     HeapKey(
00064     ) {
00065         return m_key;
00066     };
00067 
00068     const 
00069         float &
00070     HeapKey(
00071     ) const {
00072         return m_key;
00073     };
00074 
00075     const 
00076         int &
00077     HeapPos(
00078     ) const {
00079         return m_ind;
00080     };
00081 
00082 private :
00083 
00084     float m_key;
00085     int m_ind;
00086 
00087 protected :
00088 
00089     CTR_UHeapable(
00090     ) : m_key (0),
00091         m_ind (0)
00092     {
00093     };
00094 
00095     ~CTR_UHeapable(
00096     ){
00097     };
00098 };
00099     
00100 template <class HeapType>   
00101 class CTR_UHeap : public MEM_NonCopyable
00102 {
00103 
00104 public:     
00105 
00106     static
00107         CTR_UHeap *
00108     New(
00109     ) {
00110         return new CTR_UHeap();
00111     }
00112 
00113         void
00114     MakeHeap(
00115         HeapType *base
00116     ) {
00117         int i;
00118         int start = Parent(m_vector.size()-1);
00119         for (i = start; i >=0; --i) {
00120             DownHeap(base,i);
00121         }
00122     }; 
00123     
00124         void
00125     Insert(
00126         HeapType *base,
00127         int elem
00128     ) {
00129         // add element to vector
00130         m_vector.push_back(elem);
00131         base[elem].HeapPos() = m_vector.size()-1;
00132 
00133         // push the element up the heap
00134         UpHeap(base,m_vector.size()-1);
00135     }
00136 
00137     // access to the vector for initial loading of elements
00138 
00139         std::vector<int> &
00140     HeapVector(
00141     ) {
00142         return m_vector;
00143     };
00144 
00145 
00146         void
00147     Remove(
00148         HeapType *base,
00149         int i
00150     ) {
00151     
00152         // exchange with last element - pop last
00153         // element and move up or down the heap as appropriate
00154         if (m_vector.empty()) {
00155             assert(false);
00156         }
00157 
00158         if (i  != int(m_vector.size())-1) {
00159             
00160             Swap(base,i,m_vector.size() - 1);
00161             m_vector.pop_back();
00162 
00163             if (!m_vector.empty()) {
00164                 UpHeap(base,i);
00165                 DownHeap(base,i);
00166             }
00167         } else {
00168             m_vector.pop_back();
00169         }
00170     }
00171 
00172         int
00173     Top(
00174     ) const {
00175         if (m_vector.empty()) return -1;
00176         return m_vector[0];
00177     }
00178         
00179 
00180         void
00181     SC_Heap(
00182         HeapType *base
00183     ) {
00184         int i;
00185         for (i = 1; i < int(m_vector.size()) ; i++) {
00186             
00187             CTR_UHeapable * elem = base + m_vector[i];          
00188             CTR_UHeapable * p_elem = base + m_vector[Parent(i)];            
00189 
00190             assert(p_elem->HeapKey() >= elem->HeapKey());
00191             assert(elem->HeapPos() == i);
00192         }
00193 
00194     };
00195             
00196 
00197     ~CTR_UHeap(
00198     ) {
00199     };  
00200 
00201 
00202 private:
00203 
00204     CTR_UHeap(
00205     ) {
00206     };
00207 
00208 
00209     std::vector<int> m_vector;
00210         
00211 private:
00212         void 
00213     Swap(
00214         HeapType *base,
00215         int i, 
00216         int j
00217     ){
00218         std::swap(m_vector[i],m_vector[j]);
00219         
00220         CTR_UHeapable *heap_i = base + m_vector[i];
00221         CTR_UHeapable *heap_j = base + m_vector[j];
00222         
00223         // Exchange heap positions
00224         heap_i->HeapPos() = i;
00225         heap_j->HeapPos() = j;
00226     }
00227 
00228         int 
00229     Parent(
00230         unsigned int i
00231     ) {
00232         return (i-1) >> 1;
00233     }
00234         int 
00235     Left(
00236         int i
00237     ) {
00238         return (i<<1)+1;
00239     }
00240 
00241         int 
00242     Right(
00243         int i
00244     ) {
00245         return (i<<1)+2;
00246     }
00247 
00248         float
00249     HeapVal(
00250         HeapType *base,
00251         int i
00252     ) {
00253         return base[m_vector[i]].HeapKey();
00254     }
00255 
00256         void
00257     DownHeap(
00258         HeapType *base,     
00259         int i
00260     ) {
00261         int heap_size = m_vector.size();
00262 
00263         int l = Left(i);
00264         int r = Right(i);
00265 
00266         int largest;
00267         if (l < heap_size && HeapVal(base,l) > HeapVal(base,i)) {
00268             largest = l;
00269         } else {
00270             largest = i;
00271         }
00272 
00273         if (r < heap_size && HeapVal(base,r) > HeapVal(base,largest)) {
00274             largest = r;
00275         }   
00276 
00277         if (largest != i) {
00278             // exchange i and largest
00279             Swap(base,i,largest);
00280             DownHeap(base,largest);
00281         }
00282     }
00283 
00284         void
00285     UpHeap(
00286         HeapType *base,
00287         int i
00288     ) {
00289 
00290         // swap parents untill it's found a place in the heap < it's parent or
00291         // top of heap
00292 
00293         while (i > 0) {
00294             int p = Parent(i);
00295             if (HeapVal(base,i) < HeapVal(base,p)) {
00296                 break;
00297             }
00298             Swap(base,p,i);
00299             i = p;
00300         }
00301     }       
00302 };
00303 
00304 #endif
00305