71 lines
2.2 KiB
C
71 lines
2.2 KiB
C
|
#pragma once
|
||
|
|
||
|
#include <vector>
|
||
|
#include <algorithm>
|
||
|
|
||
|
namespace algo {
|
||
|
|
||
|
template<typename Iterator, typename Comparator>
|
||
|
void merge(Iterator start, Iterator middle, Iterator end, Comparator cmp, Iterator output_start) {
|
||
|
Iterator start_m = start;
|
||
|
Iterator start2 = middle + 1;
|
||
|
|
||
|
//merge from input until one half completes
|
||
|
while (start <= middle && start2 <= end) {
|
||
|
if (cmp(*start, *start2)) {
|
||
|
*output_start = *start;
|
||
|
start++;
|
||
|
} else {
|
||
|
*output_start = *start2;
|
||
|
start2++;
|
||
|
}
|
||
|
output_start++;
|
||
|
}
|
||
|
|
||
|
//try to finish first half
|
||
|
while (start <= middle) {
|
||
|
*output_start = *start;
|
||
|
start++;
|
||
|
output_start++;
|
||
|
}
|
||
|
|
||
|
while (start2 <= end) {
|
||
|
*output_start = *start2;
|
||
|
start2++;
|
||
|
output_start++;
|
||
|
}
|
||
|
|
||
|
const auto nit = std::distance(start_m, end);
|
||
|
for (auto i = 0; i <= nit; i++, start_m++, output_start++) {
|
||
|
*start_m = *output_start;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
template<typename Container, typename Iterator, typename Comparator>
|
||
|
void mergesort_splitup(Container &output_vec, Iterator start, Iterator end, Comparator cmp, Iterator output_start) {
|
||
|
Iterator middle = start;
|
||
|
Iterator output_started_from = output_start;
|
||
|
|
||
|
//move middle iterator litterally to the middle
|
||
|
std::advance(middle, std::distance(start, end) / 2);
|
||
|
//sort the first half within an recursion
|
||
|
mergesort_splitup(output_vec, start, middle, cmp, output_start);
|
||
|
|
||
|
//move output iterator
|
||
|
std::advance(output_start, std::distance(start, middle + 1));
|
||
|
//sort the second half within a recursion
|
||
|
mergesort_splitup(output_vec, middle + 1, end, cmp, output_start);
|
||
|
|
||
|
//merge everything together starting from the complete beginning
|
||
|
merge(start, middle, end, cmp, output_started_from);
|
||
|
}
|
||
|
|
||
|
template<typename Iterator, typename Comparator>
|
||
|
void mergesort(Iterator start, Iterator end, Comparator cmp) {
|
||
|
using valtype = typename std::iterator_traits<Iterator>::value_type;
|
||
|
|
||
|
std::vector<valtype> output_vec(std::distance(start, end));
|
||
|
|
||
|
}
|
||
|
}
|