Space-efficient geometric algorithms and data structures

By Ilya Katz and Hervé Brönnimann    

dynamic_sorted_vector.hpp

Go to the documentation of this file.
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.