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
Generated on Fri Jul 25 12:42:58 2008 for IT++ by Doxygen 1.5.4