|
Space-efficient geometric algorithms and data structuresBy Ilya Katz and Hervé Brönnimann |
00001 /* 00002 * Copyright © Ilya Katz and Herve Bronnimann, 2006. 00003 */ 00004 00019 #ifndef DYNAMIC_SORTED_VEC_HPP 00020 #define DYNAMIC_SORTED_VEC_HPP 00021 00022 #include <iterator> 00023 #include <cmath> 00024 00025 #define VECTOR_SIZE_CUTOFF 16 00026 00027 namespace inplaceds 00028 { 00029 00041 template <class RandomAccessIterator, class StrictWeakOrdering> 00042 inline void 00043 build_dynamic_sorted_vector(RandomAccessIterator first, RandomAccessIterator last, 00044 StrictWeakOrdering comp) 00045 { 00046 if((last-first)%VECTOR_SIZE_CUTOFF !=0 ) 00047 { 00048 std::sort(last-(last-first)%VECTOR_SIZE_CUTOFF, last, comp); 00049 00050 } 00051 00052 typedef typename 00053 std::iterator_traits<RandomAccessIterator>::difference_type Distance; 00054 00055 Distance block = VECTOR_SIZE_CUTOFF, 00056 n = (last-first) / VECTOR_SIZE_CUTOFF, 00057 t = (last-first) % VECTOR_SIZE_CUTOFF; 00058 00059 while(n!=0) 00060 { 00061 if(n%2!=0) 00062 { 00063 00064 std::sort(last-t-block, last-t, comp); 00065 00066 t = t+block; 00067 } 00068 00069 block*=2; 00070 n/=2; 00071 } 00072 cout<<endl; 00073 } 00074 00084 template <class RandomAccessIterator> 00085 inline void 00086 build_dynamic_sorted_vector(RandomAccessIterator first, RandomAccessIterator last) 00087 { 00088 build_dynamic_sorted_vector(first, last, 00089 std::less<typename std::iterator_traits<RandomAccessIterator>::value_type>()); 00090 } 00091 00104 template <class RandomAccessIterator, class StrictWeakOrdering> 00105 bool is_sorted(RandomAccessIterator first, RandomAccessIterator last, 00106 StrictWeakOrdering comp) 00107 { 00108 if(first==last || first==last-1) 00109 { 00110 return true; 00111 } 00112 for(RandomAccessIterator it=first++; it!=last-1; ++it) 00113 { 00114 if(comp(*first,*it)) 00115 { 00116 return false; 00117 } 00118 ++first; 00119 } 00120 return true; 00121 } 00122 00136 template <class RandomAccessIterator, class StrictWeakOrdering> 00137 bool 00138 is_dynamic_sorted_vector(RandomAccessIterator first, RandomAccessIterator last, 00139 StrictWeakOrdering comp) 00140 { 00141 00142 if((last-first)%VECTOR_SIZE_CUTOFF != 0) 00143 { 00144 //do nothing 00145 } 00146 00147 00148 typedef typename 00149 std::iterator_traits<RandomAccessIterator>::difference_type Distance; 00150 00151 Distance block = VECTOR_SIZE_CUTOFF, 00152 n = (last-first) / VECTOR_SIZE_CUTOFF, 00153 t = (last-first) % VECTOR_SIZE_CUTOFF; 00154 00155 while(n!=0) 00156 { 00157 if(n%2 !=0) 00158 { 00159 if(!is_sorted(last-t-block, last-t, comp)) 00160 { 00161 return false; 00162 } 00163 t = t+block; 00164 } 00165 00166 block*=2; 00167 n/=2; 00168 } 00169 00170 return true; 00171 00172 } 00173 00185 template <class RandomAccessIterator> 00186 inline bool 00187 is_dynamic_sorted_vector(RandomAccessIterator first, RandomAccessIterator last) 00188 { 00189 return is_dynamic_sorted_vector(first, last, 00190 std::less<typename std::iterator_traits<RandomAccessIterator>::value_type>()); 00191 } 00192 00193 00213 template <class RandomAccessIterator, class StrictWeakOrdering> 00214 void 00215 insert_dynamic_sorted_vector(RandomAccessIterator first, RandomAccessIterator last, 00216 StrictWeakOrdering comp) 00217 { 00218 00219 //last-first is the new size 00220 if((last-first)%VECTOR_SIZE_CUTOFF != 0) 00221 { 00222 return; 00223 } 00224 00225 typedef typename 00226 std::iterator_traits<RandomAccessIterator>::difference_type Distance; 00227 00228 Distance block = VECTOR_SIZE_CUTOFF, 00229 n = (last-first-1) / VECTOR_SIZE_CUTOFF; 00230 00231 while(n%2!=0) 00232 { 00233 block*=2; 00234 n/=2; 00235 } 00236 00237 std::sort(last-block, last, comp); 00238 } 00239 00257 template <class RandomAccessIterator> 00258 inline void 00259 insert_dynamic_sorted_vector(RandomAccessIterator first, RandomAccessIterator last) 00260 { 00261 insert_dynamic_sorted_vector(first, last, 00262 std::less<typename std::iterator_traits<RandomAccessIterator>::value_type>()); 00263 } 00264 00281 template <class RandomAccessIterator, class EqualityComparable> 00282 RandomAccessIterator 00283 find_dynamic_sorted_vector(RandomAccessIterator first, RandomAccessIterator last, 00284 const EqualityComparable& key) 00285 { 00286 00287 RandomAccessIterator result = last; 00288 00289 if((last-first)%VECTOR_SIZE_CUTOFF != 0) 00290 { 00291 result = std::find(last-(last-first)%VECTOR_SIZE_CUTOFF, last, key); 00292 } 00293 00294 if(result != last) 00295 { 00296 return result; 00297 } 00298 00299 00300 typedef typename 00301 std::iterator_traits<RandomAccessIterator>::difference_type Distance; 00302 00303 Distance block = VECTOR_SIZE_CUTOFF, 00304 n = (last-first) / VECTOR_SIZE_CUTOFF, 00305 t = (last-first) % VECTOR_SIZE_CUTOFF; 00306 00307 while(n!=0) 00308 { 00309 if(n%2!=0) 00310 { 00311 result = std::lower_bound(last-t-block, last-t, key); 00312 if(result != last-t && (*result)== key) 00313 { 00314 return result; 00315 } 00316 t = t+block; 00317 } 00318 00319 block*=2; 00320 n/=2; 00321 } 00322 00323 return last; 00324 00325 } 00326 00348 template <class RandomAccessIterator, class StrictWeakOrdering> 00349 void 00350 remove_dynamic_sorted_vector(RandomAccessIterator first, RandomAccessIterator pos, RandomAccessIterator last, 00351 StrictWeakOrdering comp) 00352 { 00353 --last; 00354 std::swap(*pos,*last); 00355 00356 typedef typename 00357 std::iterator_traits<RandomAccessIterator>::difference_type Distance; 00358 00359 Distance block = VECTOR_SIZE_CUTOFF, 00360 n = (last-first) / VECTOR_SIZE_CUTOFF, 00361 t = (last-first) % VECTOR_SIZE_CUTOFF; 00362 00363 //if there is a buffer at the end, just sort the current block 00364 if(t!=0) 00365 { 00366 //find current block 00367 while(n!=0) 00368 { 00369 if(n%2!=0) 00370 { 00371 if((pos < (last-t)) && !(pos < (last-t-block)) ) 00372 { 00373 std::sort(last-block-t, last-t, comp); 00374 return; 00375 } 00376 t+=block; 00377 } 00378 block*=2; 00379 n/=2; 00380 } 00381 } 00382 else 00383 { 00384 //otherwise, need to rebuild everything below the region 00385 //where the deleted element was located 00386 while(!(last-t < pos)) 00387 { 00388 if(n%2!=0) 00389 { 00390 std::sort(last-block-t, last-t, comp); 00391 t+=block; 00392 } 00393 00394 block*=2; 00395 n/=2; 00396 } 00397 } 00398 } 00399 00419 template <class RandomAccessIterator> 00420 inline void 00421 remove_dynamic_sorted_vector(RandomAccessIterator first, RandomAccessIterator pos, RandomAccessIterator last) 00422 { 00423 remove_dynamic_sorted_vector(first, pos, last, 00424 std::less<typename std::iterator_traits<RandomAccessIterator>::value_type>()); 00425 } 00426 00427 }//namespace 00428 #endif
Code Documentation generated Using Doxygen
Copyright © Ilya Katz and Hervé Brönnimann, 2005, 2006.