00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 # ifndef TPL_SORT_UTILS_H
00045 # define TPL_SORT_UTILS_H
00046
00047 # include <ahPair.H>
00048 # include <tpl_arrayStack.H>
00049 # include <tpl_dynArray.H>
00050 # include <tpl_dynDlist.H>
00051
00052 namespace Aleph
00053 {
00054 extern const int Insertion_Threshold;
00055
00056 extern const int Not_Found;
00057
00080 template <typename T, class Compare>
00081 void selection_sort(T a[], const size_t & n)
00082 {
00083 int i,j, min;
00084
00085 for (i = 0; i < n - 1; ++i)
00086 {
00087 for (min = i, j = i + 1; j < n; ++j)
00088 if (Compare () (a[j], a[min]))
00089 min = j;
00090 if (Compare () (a[min], a[i]))
00091 Aleph::swap(a[min], a[i]);
00092 }
00093 }
00094
00095 template <typename T>
00096 void selection_sort(T a[], const size_t & n)
00097 {
00098 selection_sort <T, Aleph::less<T> > (a, n);
00099 }
00100
00118 template <class Compare>
00119 Dlink * search_min(Dlink & list)
00120 {
00121 typename Dlink::Iterator it(list);
00122
00123 Dlink * min = it.get_current();
00124
00125 for (it.next(); it.has_current(); it.next())
00126 {
00127 Dlink * curr = it.get_current();
00128
00129 if (Compare () (curr, min))
00130 min = curr;
00131 }
00132
00133 return min;
00134 }
00150 template <class Compare>
00151 void selection_sort(Dlink & list)
00152 {
00153 Dlink aux;
00154
00155 while (not list.is_empty())
00156 {
00157 Dlink * min = search_min<Compare>(list);
00158
00159 min->del();
00160 aux.append(min);
00161 }
00162
00163 list.swap(&aux);
00164 }
00165 template <typename T, class Compare>
00166 class Compare_Dnode
00167 {
00168
00169 public:
00170
00171 bool operator () (Dlink * l1, Dlink * l2) const
00172 {
00173 Dnode<T> * n1 = static_cast<Dnode<T>*>(l1);
00174 Dnode<T> * n2 = static_cast<Dnode<T>*>(l2);
00175
00176
00177 I(n1 == l1 and n2 == l2);
00178
00179 return Compare () (n1->get_data(), n2->get_data());
00180 }
00181 };
00203 template <typename T, class Compare>
00204 void selection_sort(Dnode<T> & list)
00205 {
00206 selection_sort < Compare_Dnode<T, Compare> > (list);
00207 }
00208 template <typename T>
00209 void selection_sort(Dnode<T> & list)
00210 {
00211 selection_sort < T, Aleph::less<T> > (list);
00212 }
00235 template <typename T, class Equal> inline
00236 int sequential_search(T a[], const T & x, const int & l, const int & r)
00237 {
00238 for (int i = l; i <= r; i++)
00239 if (Equal () (a[i], x))
00240 return i;
00241
00242 return Not_Found;
00243 }
00280 template <typename T, class Equal> inline
00281 int sequential_search(DynArray<T> & a,
00282 const T & x, const int & l, const int & r)
00283 {
00284 for (int i = l; i <= r; i++)
00285 if (a.exist(i))
00286 if (Equal () (static_cast<const T&>(a.access(i)), x))
00287 return i;
00288
00289 return -1;
00290 }
00291 template <typename T> inline
00292 int sequential_search(T a[], const T & x, const int & l, const int & r)
00293 {
00294 return sequential_search<T, equal_to<T> > (a, x, l, r);
00295 }
00296
00297 template <typename T> inline
00298 int sequential_search(DynArray<T> & a,
00299 const T & x, const int & l, const int & r)
00300 {
00301 return sequential_search<T, equal_to<T> > (a, x, l, r);
00302 }
00325 template <typename T, class Equal> inline
00326 Dnode<T> * sequential_search(Dnode<T> & list, const T & x)
00327 {
00328 for (typename Dnode<T>::Iterator it(list); it.has_current(); it.next())
00329 {
00330 Dnode<T> * curr = it.get_current();
00331
00332 if (Equal () (curr->get_data(), x))
00333 return curr;
00334 }
00335
00336 return NULL;
00337 }
00338 template <typename T> inline
00339 Dnode<T> * sequential_search(Dnode<T> & list, const T & x)
00340 {
00341 return sequential_search<T, Aleph::equal_to<T> > (list, x);
00342 }
00365 template <typename T, class Equal> inline
00366 T * sequential_search(DynDlist<T> & list, const T & x)
00367 {
00368 Dnode<T> * ret =
00369 sequential_search<T, Equal > (static_cast<Dnode<T>&>(list), x);
00370
00371 return ret != NULL ? &ret->get_data() : NULL;
00372 }
00373 template <typename T> inline
00374 T * sequential_search(DynDlist<T> & list, const T & x)
00375 {
00376 return sequential_search<T, Aleph::equal_to<T> > (list, x);
00377 }
00393 template <typename T, class Compare> inline
00394 int search_extreme(T a[], const int & l, const int & r)
00395 {
00396 T extreme_index = l;
00397
00398 for (int i = l + 1; i <= r; i++)
00399 if (Compare () (a[i], a[extreme_index]))
00400 extreme_index = i;
00401
00402 return extreme_index;
00403 }
00404 template <typename T> inline
00405 int search_extreme(T a[], const int & l, const int & r)
00406 {
00407 return search_extreme<T, Aleph::less<T> > (a, l, r);
00408 }
00413 template <typename T> inline
00414 int search_min(T a[], const int & l, const int & r)
00415 {
00416 return search_extreme<T, Aleph::less<T> > (a, l, r);
00417 }
00418
00423 template <typename T> inline
00424 int search_max(T a[], const int & l, const int & r)
00425 {
00426 return search_extreme<T, Aleph::greater<T> > (a, l, r);
00427 }
00442 template <class Compare> inline
00443 Dlink * search_extreme(Dlink * list)
00444 {
00445 typename Dlink::Iterator it(*list);
00446
00447 Dlink * curr_min = it.get_current();
00448
00449 for (it.next(); it.has_current(); it.next())
00450 {
00451 Dlink curr = it.get_current();
00452
00453 if (Compare () (curr, curr_min))
00454 curr_min = curr;
00455 }
00456 return curr_min;
00457 }
00458 template <typename T, class Compare> inline
00459 Dnode<T> * search_extreme(Dnode<T> & list)
00460 {
00461 Dlink * ret= search_extreme<Compare_Dnode<T, Compare> > (list);
00462
00463 return static_cast<Dnode<T>*>(ret);
00464 }
00465
00466
00467 template <typename T> inline
00468 Dnode<T> * search_extreme(Dnode<T> & list)
00469 {
00470 return search_extreme<T, Aleph::less<T> > (list);
00471 }
00472
00487 template <typename T, class Compare> inline
00488 T * search_extreme(DynDlist<T> & list)
00489 {
00490 Dnode<T> * ret =
00491 search_extreme <T, Compare> (static_cast<Dnode<T>&>(list));
00492
00493 return ret != NULL ? &(ret->get_data()) : NULL;
00494 }
00495
00496 template <typename T> inline
00497 T * search_extreme(DynDlist<T> & list)
00498 {
00499 return search_extreme<T, Aleph::less<T> > (list);
00500 }
00501
00506 template <typename T> inline
00507 T * search_min(DynDlist<T> & list)
00508 {
00509 return search_extreme<T, Aleph::less<T> > (list);
00510 }
00511
00516 template <typename T> inline
00517 T * search_max(DynDlist<T> & list)
00518 {
00519 return search_extreme<T, Aleph::greater<T> > (list);
00520 }
00547 template <typename T, class Compare>
00548 void insertion_sort(T a[], const size_t & l, const size_t & r)
00549 {
00550 int i,j;
00551 T tmp;
00552
00553 for (i = l; i <= r; ++i)
00554 {
00555 tmp = a[i];
00556 for (j = i; j > l and Compare() (tmp, a[j - 1]); --j)
00557 a[j] = a[j - 1];
00558 a[j] = tmp;
00559 }
00560 }
00561 template <typename T>
00562 void insertion_sort(T a[], const size_t & l, const size_t & r)
00563 {
00564 insertion_sort <T, Aleph::less<T> > (a, l, r);
00565 }
00578 template <class Compare>
00579 void insert_sorted(Dlink & list, Dlink * p)
00580 {
00581 typename Dlink::Iterator it(list);
00582
00583 while (it.has_current() and Compare () (it.get_current(), p))
00584 it.next();
00585
00586 if (it.has_current())
00587 it.get_current()->append(p);
00588 else
00589 list.append(p);
00590 }
00602 template <class Compare>
00603 void insertion_sort(Dlink & list)
00604 {
00605 Dlink aux;
00606
00607 while (not list.is_empty())
00608 {
00609 Dlink * p = list.remove_next();
00610
00611 insert_sorted<Compare>(aux, p);
00612 }
00613
00614 list.swap(&aux);
00615 }
00628 template <typename T, class Compare>
00629 void insertion_sort(Dnode<T> & list)
00630 {
00631 insertion_sort < Compare_Dnode<T, Compare> > (list);
00632 }
00633 template <typename T>
00634 void insertion_sort(Dnode<T> & list)
00635 {
00636 insertion_sort < T, Aleph::less<T> > (list);
00637 }
00638 template <typename T>
00639 int binary_search_rec(T a[], const T & x, const int & l, const int & r)
00640 {
00641 return binary_search_rec <T, Aleph::less<T> > (a, x, l, r);
00642 }
00643 template <typename T, class Compare>
00644 void merge(T a[], const int & l, const int & m, const int & r)
00645 {
00646 int i, j, k;
00647 T b[r - l + 1];
00648
00649 for (i = l; i <= m; i++)
00650 b[i] = a[i];
00651 for (j = r, i = m + 1; i <= r; i++, j--)
00652 b[i] = a[j];
00653 for (k = l, i = l, j = r; k <= r; k++)
00654 if (Compare() (b[i] < b[j]))
00655 a[k] = b[i++];
00656 else
00657 a[k] = b[j--];
00658 }
00659
00684 template <typename T, class Compare>
00685 void mergesort(T a[], const int & l, const int & r)
00686 {
00687 if (l >= r) return;
00688
00689 const int m = (l + r)/2;
00690
00691 mergesort<T, Compare>(a, l, m);
00692 mergesort<T, Compare>(a, m + 1, r);
00693
00694 merge<T, Compare>(a, l, m, r);
00695 }
00696 template <typename T>
00697 void mergesort(T a[], const int & l, const int & r)
00698 {
00699 mergesort <T, Aleph::less<T> > (a, l, r);
00700 }
00716 template <class Compare>
00717 void merge_lists(Dlink & l1, Dlink & l2, Dlink & result)
00718 {
00719
00720 I(result.is_empty());
00721
00722 while (not l1.is_empty() and not l2.is_empty())
00723 if (Compare () (l1.get_next(), l2.get_next()))
00724 result.append(l1.remove_next());
00725 else
00726 result.append(l2.remove_next());
00727
00728 if (l1.is_empty())
00729 result.concat_list(&l2);
00730 else
00731 result.concat_list(&l1);
00732
00733 I(l1.is_empty() and l2.is_empty());
00734
00735 }
00751 template <class T, class Compare>
00752 void merge_lists(Dnode<T> & l1, Dnode<T> & l2, Dnode<T> & result)
00753 {
00754 merge_lists<Compare_Dnode<T, Compare> >(l1, l2, result);
00755 }
00771 template <class Compare>
00772 void mergesort(Dlink & list)
00773 {
00774 if (list.is_unitarian_or_empty())
00775 return;
00776
00777 Dlink l, r;
00778
00779 list.split_list(l, r);
00780
00781 mergesort <Compare> (l);
00782 mergesort <Compare> (r);
00783
00784 merge_lists <Compare> (l, r, list);
00785 }
00809 template <typename T, class Compare>
00810 void mergesort(Dnode<T> & list)
00811 {
00812 mergesort < Compare_Dnode<T, Compare> > (list);
00813 }
00814
00815 template <typename T>
00816 void mergesort(Dnode<T> & list)
00817 {
00818 mergesort < T, Aleph::less<T> > (list);
00819 }
00820
00844 template <typename T, class Compare>
00845 void mergesort(DynDlist<T> & list)
00846 {
00847 mergesort < Compare_Dnode<T, Compare> > (list);
00848 }
00849
00850
00851 template <typename T, class Compare>
00852 int select_pivot(T a[], const int & l, const int & r);
00853
00854 template <typename T, class Compare>
00855 int partition(T a[], const int & l, const int & r)
00856 {
00857 const int p = select_pivot <T, Compare> (a, l, r);
00858 Aleph::swap(a[p], a[r]);
00859 T pivot = a[r];
00860 int i = l - 1,
00861 j = r;
00862
00863 while (true)
00864 {
00865
00866 while (Compare() (a[++i], pivot)) { }
00867 while (Compare() (pivot, a[--j]))
00868 if (j == l)
00869 break;
00870
00871 if (i >= j)
00872 break;
00873
00874
00875 Aleph::swap(a[i], a[j]);
00876 }
00877 Aleph::swap(a[i], a[r]);
00878
00879 return i;
00880 }
00881
00918 template <typename T, class Compare>
00919 void quicksort_rec(T a[], const int & l, const int & r)
00920 {
00921 if (l >= r) return;
00922
00923 const int pivot = partition <T, Compare> (a, l, r);
00924
00925 quicksort_rec <T, Compare> (a, l, pivot - 1);
00926 quicksort_rec <T, Compare> (a, pivot + 1, r);
00927 }
00928 template <typename T>
00929 void quicksort_rec(T a[], const int & l, const int & r)
00930 {
00931 quicksort_rec<T, Aleph::less<T> > (a, l, r);
00932 }
00948 template <typename T, class Compare>
00949 void quicksort_rec_min(T a[], const int & l, const int & r)
00950 {
00951 if (r <= l)
00952 return;
00953
00954 const int pivot = partition<T, Compare>(a, l, r);
00955
00956 if (pivot - l < r - pivot)
00957 {
00958 quicksort_rec_min<T, Compare>(a, l, pivot - 1);
00959 quicksort_rec_min<T, Compare>(a, pivot + 1, r);
00960 }
00961 else
00962 {
00963 quicksort_rec_min<T, Compare>(a, pivot + 1, r);
00964 quicksort_rec_min<T, Compare>(a, l, pivot - 1);
00965 }
00966 }
00967 template <typename T>
00968 void quicksort_rec_min(T a[], const int & l, const int & r)
00969 {
00970 quicksort_rec_min <T, Aleph::less<T> > (a, l, r);
00971 }
00972 template <typename T, class Compare>
00973 int select_pivot(T a[], const int & l, const int & r)
00974 {
00975
00976 I(l <= r);
00977
00978 if (l - r <= 2)
00979 return r;
00980
00981 const int m = (r + l) / 2;
00982
00983 int p = Compare () (a[l], a[m]) ? m : l;
00984
00985 return Compare () (a[r], a[m]) ? r : p;
00986 }
01023 template <typename T, class Compare>
01024 void quicksort(T a[], const int & l, const int & r)
01025 {
01026
01027 if (r <= l)
01028 return;
01029
01030 typedef typename Aleph::pair<int, int> Partition;
01031
01032 FixedStack<Partition, 32> stack;
01033
01034 stack.push(Partition(l, r));
01035
01036 while (stack.size() > 0)
01037 {
01038 const Partition p = stack.pop();
01039
01040 const int pivot = partition<T, Compare>(a, p.first, p.second);
01041
01042 if (pivot - p.first < p.second - pivot)
01043 {
01044 stack.push(Partition(pivot + 1, p.second));
01045 stack.push(Partition(p.first, pivot - 1));
01046 }
01047 else
01048 {
01049 stack.push(Partition(p.first, pivot - 1));
01050 stack.push(Partition(pivot + 1, p.second));
01051 }
01052 }
01053 }
01054 template <typename T>
01055 void quicksort(T a[], const int & l, const int & r)
01056 {
01057 quicksort<T, Aleph::less<T> > (a, l, r);
01058 }
01071 template <class Compare>
01072 void quicksort(Dlink & list)
01073 {
01074 if (list.is_unitarian_or_empty())
01075 return;
01076
01077 Dlink * pivot = list.remove_next();
01078
01079 Dlink smaller;
01080 Dlink bigger;
01081
01082 while (not list.is_empty())
01083 {
01084 Dlink * p = list.remove_next();
01085
01086 if (Compare () (p, pivot))
01087 smaller.append(p);
01088 else
01089 bigger.append(p);
01090 }
01091
01092 quicksort <Compare> (bigger);
01093 quicksort <Compare> (smaller);
01094
01095 list.concat_list(&smaller);
01096 list.append(pivot);
01097 list.concat_list(&bigger);
01098 }
01122 template <typename T, class Compare>
01123 void quicksort(Dnode<T> & list)
01124 {
01125 quicksort < Compare_Dnode<T, Compare> > (list);
01126 }
01127
01128 template <typename T>
01129 void quicksort(Dnode<T> & list)
01130 {
01131 quicksort < T, Aleph::less<T> > (list);
01132 }
01173 template <typename T, class Compare>
01174 void quicksort_insertion(T a[], const int & l, const int & r)
01175 {
01176 if (r <= l) return;
01177
01178 const int pivot = partition<T, Compare>(a, l, r);
01179
01180 const int l_size = pivot - l;
01181 const int r_size = r - pivot;
01182
01183 bool left_done = false;
01184 bool right_done = false;
01185
01186 if (l_size <= Aleph::Insertion_Threshold)
01187 {
01188 insertion_sort<T, Compare>(a, l, pivot - 1);
01189 left_done = true;
01190 }
01191
01192 if (r_size <= Aleph::Insertion_Threshold)
01193 {
01194 insertion_sort<T, Compare>(a, pivot + 1, r);
01195 right_done = true;
01196 }
01197
01198 if (left_done and right_done)
01199 return;
01200
01201 if (left_done)
01202 {
01203 quicksort_insertion<T, Compare>(a, pivot + 1, r);
01204
01205 return;
01206 }
01207
01208 if (right_done)
01209 {
01210 quicksort_insertion<T, Compare>(a, l, pivot - 1);
01211
01212 return;
01213 }
01214
01215
01216
01217
01218 if (l_size < r_size)
01219 {
01220 quicksort_insertion <T, Compare> (a, l, pivot - 1);
01221 quicksort_insertion <T, Compare> (a, pivot + 1, r);
01222 }
01223 else
01224 {
01225 quicksort_insertion <T, Compare> (a, pivot + 1, r);
01226 quicksort_insertion <T, Compare> (a, l, pivot - 1);
01227 }
01228 }
01229 template <typename T>
01230 void quicksort_insertion(T a[], const int & l, const int & r)
01231 {
01232 quicksort_insertion <T, Aleph::less<T> > (a, l, r);
01233 }
01264 template <typename T, class Compare>
01265 int random_search(T a[], const T & x, const int & l, const int & r)
01266 {
01267 if (l > r)
01268 return Not_Found;
01269
01270 const int pivot = partition<T, Compare>(a, l, r);
01271
01272 if (Compare() (x, a[pivot]))
01273 return random_search(a, l, pivot - 1);
01274 else if (Compare() (a[pivot], x))
01275 return random_search(a, pivot + 1, r);
01276
01277 return pivot;
01278 }
01279 template <typename T>
01280 int random_search(T a[], const T & x, const int & l, const int & r)
01281 {
01282 return random_search <T, Aleph::less<T> > (a, x, l, r);
01283 }
01309 template <typename T, class Compare>
01310 Dnode<T> * dlink_random_search(Dlink & list, const T & x)
01311 {
01312 if (list.is_empty())
01313 return NULL;
01314
01315 Dnode<T> * pivot = static_cast<Dnode<T>*>(list.remove_next());
01316 Dnode<T> item(x);
01317 Dnode<T> * item_ptr = &item;
01318
01319 Dlink smaller;
01320 Dlink bigger;
01321
01322 while (not list.is_empty())
01323 {
01324 Dlink * p = list.remove_next();
01325
01326 if (Compare () (p, pivot))
01327 smaller.append(p);
01328 else
01329 bigger.append(p);
01330 }
01331
01332 Dnode<T> * ret_val = NULL;
01333
01334 if (Compare () (item_ptr, pivot))
01335 ret_val = dlink_random_search <T, Compare> (smaller, x);
01336 else if (Compare () (pivot, item_ptr))
01337 ret_val = dlink_random_search <T, Compare> (bigger, x);
01338 else
01339 ret_val = pivot;
01340
01341
01342 I(list.is_empty());
01343
01344 list.swap(&smaller);
01345 list.append(pivot);
01346 list.concat_list(&bigger);
01347
01348 return ret_val;
01349 }
01378 template <typename T, class Compare_T>
01379 Dnode<T> * random_search(Dlink & list, const T & x)
01380 {
01381 return dlink_random_search <T, Compare_Dnode<T, Compare_T> > (list, x);
01382 }
01383
01384 template <typename T>
01385 Dnode<T> * random_search(Dlink & list, const T & x)
01386 {
01387 return random_search <T, Aleph::less<T> > (list, x);
01388 }
01389
01418 template <typename T, class Compare>
01419 T * random_search(DynDlist<T> & list, const T & x)
01420 {
01421 Dnode<T> * p = dlink_random_search <T, Compare_Dnode<T, Compare> > (list, x);
01422
01423 return p == NULL ? NULL : &(p->get_data());
01424 }
01425
01426 template <typename T>
01427 T * random_search(DynDlist<T> & list, const T & x)
01428 {
01429 return random_search <T, Aleph::less<T> > (list, x);
01430 }
01431 template <typename T, class Compare> static inline
01432 const T & __random_select(T a[], const int & i, const int & l, const int & r)
01433 {
01434 const int pivot = partition<T, Compare>(a, l, r);
01435
01436 if (i == pivot)
01437 return a[i];
01438
01439 if (i < pivot)
01440 return __random_select<T, Compare>(a, i, l, pivot - 1);
01441 else
01442 return __random_select<T, Compare>(a, i, pivot + 1, r);
01443 }
01470 template <typename T, class Compare>
01471 const T & random_select(T a[], const int & i, const int & n)
01472 {
01473 if (i >= n)
01474 throw std::out_of_range("index out of range");
01475
01476 return __random_select(a, i, 0, n - 1);
01477 }
01478 template <typename T>
01479 const T & random_select(T a[], const int & i, const int & n)
01480 {
01481 return random_select <T, Aleph::less<T> > (a, i, 0, n - 1);
01482 }
01504 template <class Compare>
01505 Dlink * dlink_random_select(Dlink & list, const size_t & i)
01506 {
01507 if (list.is_empty())
01508 return NULL;
01509
01510 Dlink * pivot = list.remove_next();
01511
01512 Dlink smaller;
01513 Dlink bigger;
01514
01515 size_t smaller_count = 0,
01516 bigger_count = 0;
01517
01518 while (not list.is_empty())
01519 {
01520 Dlink * p = list.remove_next();
01521
01522 if (Compare () (p, pivot))
01523 {
01524 smaller.append(p); ++smaller_count;
01525 }
01526 else
01527 {
01528 bigger.append(p); ++bigger_count;
01529 }
01530 }
01531
01532 if (i >= bigger_count)
01533 throw std::out_of_range("index of selection greater than list's size");
01534
01535
01536 Dlink * ret_val = NULL;
01537
01538 if (i == smaller_count)
01539 ret_val = pivot;
01540 else if (i < smaller_count)
01541 ret_val = dlink_random_select <Compare> (smaller, i);
01542 else
01543 ret_val = dlink_random_select <Compare> (bigger, i - (smaller_count + 1));
01544
01545 list.concat_list(&smaller);
01546 list.append(pivot);
01547 list.concat_list(&bigger);
01548
01549 return ret_val;
01550 }
01577 template <typename T, class Compare>
01578 Dnode<T> * random_select(Dlink & list, const size_t & i)
01579 {
01580 return static_cast <Dnode<T>*>
01581 (dlink_random_select < Compare_Dnode<T, Compare> > (list, i));
01582 }
01583 template <typename T>
01584 Dnode<T> * random_select(Dlink & list, const size_t & i)
01585 {
01586 return random_select < T, Aleph::less<T> > (list, i);
01587 }
01588
01615 template <typename T, class Compare>
01616 T * random_select(DynDlist<T> list, const size_t & i)
01617 {
01618 Dlink * link = dlink_random_select <Compare_Dnode<T, Compare> > (list, i);
01619
01620 Dnode<T> * p = static_cast<Dnode<T>*>(link);
01621
01622 return p != NULL ? &(p->get_data()) : NULL;
01623 }
01624
01625 template <typename T>
01626 T * random_select(DynDlist<T> list, const size_t & i)
01627 {
01628 return random_select <T, Aleph::less<T> > (list, i);
01629 }
01662 template <typename T, class Compare>
01663 int binary_search_rec(T a[], const T & x, const int & l, const int & r)
01664 {
01665 const int m = (l + r) / 2;
01666
01667 if (l > r)
01668 return m;
01669
01670 if (Compare() (x, a[m]))
01671 return binary_search_rec<T, Compare>(a, l, m - 1);
01672 else if (Compare() (a[m], x))
01673 return binary_search_rec<T, Compare>(a, m + 1, r);
01674
01675 return m;
01676 }
01677
01678 }
01679
01680 # endif // TPL_SORT_UTILS_H
01681