General Purpose library for Freestanding C++ and POSIX systems
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

75 lines
2.4 KiB

#pragma once
#include <gp/algorithms/move.hpp>
#include <gp/algorithms/partition.hpp>
#include <iostream>
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::bubble_sort(first, last, predicate);
}
}