|
Blender
V2.59
|
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