|
|
- #pragma once
- #include <gp/algorithms/move.hpp>
- #include <gp/algorithms/partition.hpp>
-
- namespace gp {
-
- namespace __details {
- template<typename it_t, typename pred>
- void selection_sort(it_t first, it_t last, pred predicate = pred{}) {
-
- while(first != last) {
- it_t traveler = first;
- it_t it = first;
- it++;
- for(;it!=last;it++) {
- if(predicate(*it, *traveler)) traveler = it;
- }
- gp::swap(*first, *traveler);
- first++;
- }
- }
-
- template<typename it_t, typename pred>
- bool sort2(auto it0, auto it1, pred predicate = pred{}){
- if(it0 != it1 && predicate(*it1, *it0)) {
- gp::swap(*it0, *it1);
- return true;
- }
- return false;
- };
- /*
- template<typename it_t, typename pred>
- void quick_sort(it_t first, it_t last, pred predicate = pred{}) {
- using __details::sort2;
- if(last - first <= 2) {
- auto nit = first + (size_t)(last == first + 1);
- __details::sort2<it_t>(first, nit, predicate);
- return;
- }
- auto pivot_v = *(first + (last - first)/2);
- auto pivot = gp::partition(first, last, [&](auto& a) -> bool{
- return predicate(a, pivot_v);
- });
- gp::__details::quick_sort(first, pivot, predicate);
- gp::__details::quick_sort(pivot, last, predicate);
- }
- */
- template<typename it_t, typename pred>
- void bubble_sort(it_t first, it_t last, pred predicate = pred{}) {
- if(last - first <= 2) {
- auto nit = first + (size_t)(last == first + 1);
- __details::sort2<it_t>(first, nit, predicate);
- return;
- }
- size_t swaps;
- do {
- swaps = 0;
- auto it = first;
- auto nit = it + 1;
- for(;;) {
- swaps += __details::sort2<it_t>(it, nit, predicate);
- ++it; ++nit;
- if(nit == last) break;
- }
- } while(swaps);
- }
- }
-
-
- template<typename it_t, typename pred>
- void sort(it_t first, it_t last, pred predicate = pred{}) {
- return gp::__details::selection_sort(first, last, predicate);
- }
- }
|