IT++ Logo

sort.h

Go to the documentation of this file.
00001 
00030 #ifndef SORT_H
00031 #define SORT_H
00032 
00033 #include <itpp/base/vec.h>
00034 #include <itpp/base/converters.h>
00035 #include <itpp/base/math/log_exp.h>
00036 
00037 
00038 namespace itpp
00039 {
00040 
00049 enum SORTING_METHOD { INTROSORT = 0, QUICKSORT = 1, HEAPSORT = 2,
00050                       INSERTSORT = 3
00051                     };
00052 
00099 template<class T>
00100 class Sort
00101 {
00102 public:
00104   Sort(SORTING_METHOD method = INTROSORT): sort_method(method) {}
00105 
00107   void set_method(SORTING_METHOD method) { sort_method = method; }
00108 
00110   SORTING_METHOD get_method() const { return sort_method; }
00111 
00119   void sort(int low, int high, Vec<T> &data);
00120 
00128   ivec sort_index(int low, int high, const Vec<T> &data);
00129 
00143   void intro_sort(int low, int high, int max_depth, Vec<T> &data);
00144 
00158   ivec intro_sort_index(int low, int high, int max_depth,
00159                         const Vec<T> &data);
00160 
00161 private:
00162   SORTING_METHOD sort_method;
00163 
00164   void IntroSort(int low, int high, int max_depth, T data[]);
00165   void IntroSort_Index(int low, int high, int max_depth, int indexlist[],
00166                        const T data[]);
00167 
00168   void QuickSort(int low, int high, T data[]);
00169   void QuickSort_Index(int low, int high, int indexlist[], const T data[]);
00170 
00171   void HeapSort(int low, int high, T data[]);
00172   void HeapSort_Index(int low, int high, int indexlist[], const T data[]);
00173 
00174   void InsertSort(int low, int high, T data[]);
00175   void InsertSort_Index(int low, int high, int indexlist[], const T data[]);
00176 };
00177 
00178 
00187 template<class T>
00188 void sort(Vec<T> &data, SORTING_METHOD method = INTROSORT)
00189 {
00190   Sort<T> s(method);
00191   s.sort(0, data.size() - 1, data);
00192 }
00193 
00203 template<class T>
00204 ivec sort_index(const Vec<T> &data, SORTING_METHOD method = INTROSORT)
00205 {
00206   Sort<T> s(method);
00207   return s.sort_index(0, data.size() - 1, data);
00208 }
00209 
00210 
00211 // ----------------------------------------------------------------------
00212 // Public functions for various sorting methods
00213 // ----------------------------------------------------------------------
00214 
00215 template<class T>
00216 void Sort<T>::sort(int low, int high, Vec<T> &data)
00217 {
00218   int N = data.size();
00219 
00220   it_assert((low >= 0) && (high > low) && (high < N), "Sort::sort(): "
00221             "low or high out of bounds");
00222 
00223   switch (sort_method) {
00224   case INTROSORT:
00225     IntroSort(low, high, levels2bits(N), data._data());
00226     break;
00227   case QUICKSORT:
00228     QuickSort(low, high, data._data());
00229     break;
00230   case HEAPSORT:
00231     HeapSort(low, high, data._data());
00232     break;
00233   case INSERTSORT:
00234     InsertSort(low, high, data._data());
00235     break;
00236   default:
00237     it_error("Sort<T>::sort(): Unknown sorting method");
00238   }
00239 }
00240 
00241 
00242 template<class T>
00243 ivec Sort<T>::sort_index(int low, int high, const Vec<T> &data)
00244 {
00245   int N = data.size();
00246 
00247   it_assert((low >= 0) && (high > low) && (high < N), "Sort::sort(): "
00248             "low or high out of bounds");
00249 
00250   ivec indexlist(N);
00251   for (int i = 0; i < N; ++i) {
00252     indexlist(i) = i;
00253   }
00254 
00255   switch (sort_method) {
00256   case INTROSORT:
00257     IntroSort_Index(low, high, levels2bits(N), indexlist._data(),
00258                     data._data());
00259     break;
00260   case QUICKSORT:
00261     QuickSort_Index(low, high, indexlist._data(), data._data());
00262     break;
00263   case HEAPSORT:
00264     HeapSort_Index(low, high, indexlist._data(), data._data());
00265     break;
00266   case INSERTSORT:
00267     InsertSort_Index(low, high, indexlist._data(), data._data());
00268     break;
00269   default:
00270     it_error("Sort<T>::sort_index(): Unknown sorting method");
00271   }
00272 
00273   return indexlist;
00274 }
00275 
00276 
00277 // INTRO SORT
00278 template<class T>
00279 void Sort<T>::intro_sort(int low, int high, int max_depth, Vec<T> &data)
00280 {
00281   it_assert((low >= 0) && (high > low) && (high < data.size()),
00282             "Sort::sort(): low or high out of bounds");
00283   IntroSort(low, high, max_depth, data._data());
00284 }
00285 
00286 // INTRO SORT INDEX
00287 template<class T>
00288 ivec Sort<T>::intro_sort_index(int low, int high, int max_depth,
00289                                const Vec<T> &data)
00290 {
00291   int N = data.size();
00292   it_assert((low >= 0) && (high > low) && (high < N),
00293             "Sort::sort(): low or high out of bounds");
00294 
00295   ivec indexlist(N);
00296   for (int i = 0; i < N; ++i) {
00297     indexlist(i) = i;
00298   }
00299 
00300   IntroSort_Index(low, high, max_depth, indexlist._data(), data._data());
00301 
00302   return indexlist;
00303 }
00304 
00305 
00306 // ----------------------------------------------------------------------
00307 // Private functions for sorting methods
00308 // ----------------------------------------------------------------------
00309 
00310 template<class T>
00311 void Sort<T>::IntroSort(int low, int high, int max_depth, T data[])
00312 {
00313   if (high - low > 16) {
00314     max_depth--;
00315     if (max_depth == 0) {
00316       HeapSort(low, high, data);
00317       return;
00318     }
00319 
00320     if (high > low) {
00321       T a = data[low];
00322       int plow = low;
00323       int phigh = high;
00324       T test = data[phigh];
00325       while (plow < phigh) {
00326         if (test < a) {
00327           data[plow] = test;
00328           plow++;
00329           test = data[plow];
00330         }
00331         else {
00332           data[phigh] = test;
00333           phigh--;
00334           test = data[phigh];
00335         }
00336       }
00337       data[plow] = a;
00338       IntroSort(low, plow - 1, max_depth, data);
00339       IntroSort(plow + 1, high, max_depth, data);
00340       return;
00341     }
00342   }
00343   else {
00344     InsertSort(low, high, data);
00345     return;
00346   }
00347 }
00348 
00349 template<class T>
00350 void Sort<T>::IntroSort_Index(int low, int high, int max_depth,
00351                               int indexlist[], const T data[])
00352 {
00353   if (high - low > 16) {
00354     max_depth--;
00355     if (max_depth == 0) {
00356       HeapSort_Index(low, high, indexlist, data);
00357       return;
00358     }
00359 
00360     if (high > low) {
00361       int aindex = indexlist[low];
00362       T a = data[aindex];
00363       int plow = low;
00364       int phigh = high;
00365       int testindex = indexlist[phigh];
00366       T test = data[testindex];
00367       while (plow < phigh) {
00368         if (test < a) {
00369           indexlist[plow] = testindex;
00370           plow++;
00371           testindex = indexlist[plow];
00372           test = data[testindex];
00373         }
00374         else {
00375           indexlist[phigh] = testindex;
00376           phigh--;
00377           testindex = indexlist[phigh];
00378           test = data[testindex];
00379         }
00380       }
00381       indexlist[plow] = aindex;
00382       IntroSort_Index(low, plow - 1, max_depth, indexlist, data);
00383       IntroSort_Index(plow + 1, high, max_depth, indexlist, data);
00384     }
00385   }
00386   else {
00387     InsertSort_Index(low, high, indexlist, data);
00388     return;
00389   }
00390 }
00391 
00392 template <class T>
00393 void Sort<T>::QuickSort(int low, int high, T data[])
00394 {
00395   if (high > low) {
00396     T a = data[low];
00397     int plow = low;
00398     int phigh = high;
00399     T test = data[phigh];
00400     while (plow < phigh) {
00401       if (test < a) {
00402         data[plow] = test;
00403         plow++;
00404         test = data[plow];
00405       }
00406       else {
00407         data[phigh] = test;
00408         phigh--;
00409         test = data[phigh];
00410       }
00411     }
00412     data[plow] = a;
00413     QuickSort(low, plow - 1, data);
00414     QuickSort(plow + 1, high, data);
00415   }
00416 }
00417 
00418 template<class T>
00419 void Sort<T>::QuickSort_Index(int low, int high, int indexlist[],
00420                               const T data[])
00421 {
00422   if (high > low) {
00423     int aindex = indexlist[low];
00424     T a = data[aindex];
00425     int plow = low;
00426     int phigh = high;
00427     int testindex = indexlist[phigh];
00428     T test = data[testindex];
00429     while (plow < phigh) {
00430       if (test < a) {
00431         indexlist[plow] = testindex;
00432         plow++;
00433         testindex = indexlist[plow];
00434         test = data[testindex];
00435       }
00436       else {
00437         indexlist[phigh] = testindex;
00438         phigh--;
00439         testindex = indexlist[phigh];
00440         test = data[testindex];
00441       }
00442     }
00443     indexlist[plow] = aindex;
00444     QuickSort_Index(low, plow - 1, indexlist, data);
00445     QuickSort_Index(plow + 1, high, indexlist, data);
00446   }
00447 }
00448 
00449 template<class T>
00450 void Sort<T>::HeapSort(int low, int high, T data[])
00451 {
00452   int size = (high + 1) - low;
00453   int i = size / 2;
00454   T temp;
00455   while (1) {
00456     if (i > 0)
00457       temp = data[--i + low];
00458     else {
00459       if (size-- == 0)
00460         break;
00461       temp = data[size + low];
00462       data[size + low] = data[low];
00463     }
00464 
00465     int parent = i;
00466     int child = i * 2 + 1;
00467 
00468     while (child < size) {
00469       if (child + 1 < size  &&  data[child + 1 + low] > data[child + low])
00470         child++;
00471       if (data[child + low] > temp) {
00472         data[parent + low] = data[child + low];
00473         parent = child;
00474         child = parent * 2 + 1;
00475       }
00476       else
00477         break;
00478     }
00479     data[parent + low] = temp;
00480   }
00481 }
00482 
00483 template<class T>
00484 void Sort<T>::HeapSort_Index(int low, int high, int indexlist[],
00485                              const T data[])
00486 {
00487   int size = (high + 1) - low;
00488   int i = size / 2;
00489 
00490   while (1) {
00491     T tempValue;
00492     int tempIndex;
00493     if (i > 0) {
00494       i--;
00495       tempValue = data[indexlist[i + low]];
00496       tempIndex = indexlist[i + low];
00497     }
00498     else {
00499       if (size-- == 0)
00500         break;
00501       tempValue = data[indexlist[size + low]];
00502       tempIndex = indexlist[size + low];
00503       indexlist[size+low] = indexlist[low];
00504     }
00505 
00506     int parent = i;
00507     int child = i * 2 + 1;
00508 
00509     while (child < size) {
00510       if ((child + 1 < size)
00511           && data[indexlist[child + 1 + low]] > data[indexlist[child + low]])
00512         child++;
00513       if (data[indexlist[child + low]] > tempValue) {
00514         indexlist[parent + low] = indexlist[child + low];
00515         parent = child;
00516         child = parent * 2 + 1;
00517       }
00518       else
00519         break;
00520     }
00521     indexlist[parent + low] = tempIndex;
00522   }
00523 }
00524 
00525 template<class T>
00526 void Sort<T>::InsertSort(int low, int high, T data[])
00527 {
00528   for (int i = low + 1; i <= high; i++) {
00529     T value = data[i];
00530     int j;
00531     for (j = i - 1; j >= low && data[j] > value; j--) {
00532       data[j + 1] = data[j];
00533     }
00534     data[j + 1] = value;
00535   }
00536 }
00537 
00538 template<class T>
00539 void Sort<T>::InsertSort_Index(int low, int high, int indexlist[],
00540                                const T data[])
00541 {
00542   for (int i = low + 1; i <= high; i++) {
00543     T value = data[indexlist[i]];
00544     int tempIndex = indexlist[i];
00545     int j;
00546     for (j = i - 1; j >= low && data[indexlist[j]] > value; j--) {
00547       indexlist[j + 1] = indexlist[j];
00548     }
00549     indexlist[j + 1] = tempIndex;
00550   }
00551 }
00552 
00553 
00554 } // namespace itpp
00555 
00556 #endif // #ifndef SORT_H
SourceForge Logo

Generated on Fri Jul 25 12:42:58 2008 for IT++ by Doxygen 1.5.4