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