Move algo to class

This commit is contained in:
Robin Dietzel 2023-11-01 10:19:25 +01:00
parent ab129bc6c8
commit 78562a45ba
2 changed files with 62 additions and 57 deletions

View File

@ -16,7 +16,7 @@ an arbitrary number of processors, as Amdahls and Gustafson-Barsis laws
require. require.
Assuming that this equal division is possible, estimate α, i.e., the part of the Assuming that this equal division is possible, estimate α, i.e., the part of the
program that can be parallelized, by using a profiler like gprof or valgrind to program that can be parallelized, by using a profiler like gprof or valgrind to
measure the duration of mergesorts execution relative to the overall execution measure the duration of sorts execution relative to the overall execution
time. Use this number to estimate the predicted speedup for your program. time. Use this number to estimate the predicted speedup for your program.
Does α depend on the size of the input? If it does, how should you modify Does α depend on the size of the input? If it does, how should you modify
your predictions and their graphical illustration? your predictions and their graphical illustration?
@ -52,7 +52,7 @@ int main(int argc, char *argv[]) {
auto t1 = std::chrono::high_resolution_clock::now(); auto t1 = std::chrono::high_resolution_clock::now();
algo::mergesort(dataset.begin(), dataset.end(), [](int32_t a, int32_t b) { algo::MergeSort_v1::sort(dataset.begin(), dataset.end(), [](int32_t a, int32_t b) {
return (a > b); return (a > b);
}); });

View File

@ -5,71 +5,76 @@
namespace algo { namespace algo {
template<typename Iterator, typename Comparator> class MergeSort_v1 {
void merge(Iterator start, Iterator middle, Iterator end, Comparator cmp, Iterator output_start) { private:
Iterator start_m = start; template<typename Iterator, typename Comparator>
Iterator begin = output_start; static auto merge(Iterator start, Iterator middle, Iterator end, Comparator cmp, Iterator output_start) -> void {
Iterator start2 = middle + 1; Iterator start_m = start;
Iterator begin = output_start;
Iterator start2 = middle + 1;
//merge from input until one half completes //merge from input until one half completes
while (start <= middle && start2 <= end) { while (start <= middle && start2 <= end) {
if (cmp(*start, *start2)) { 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; *output_start = *start;
start++; start++;
} else { output_start++;
}
while (start2 <= end) {
*output_start = *start2; *output_start = *start2;
start2++; start2++;
output_start++;
} }
output_start++;
const auto size = std::distance(start_m, end);
for (auto i = 0; i <= size; i++, start_m++, begin++) {
*start_m = *begin;
}
} }
//try to finish first half template<typename Container, typename Iterator, typename Comparator>
while (start <= middle) { static auto ms_split(Container &output_vec, Iterator start, Iterator end, Comparator cmp, Iterator output_start) -> void {
*output_start = *start; Iterator mid = start;
start++; Iterator begin = output_start;
output_start++;
if (std::distance(start, end) < 1) {
return;
} else {
//move mid iterator litterally to the mid
std::advance(mid, std::distance(start, end) / 2);
//sort the first half within an recursion
ms_split(output_vec, start, mid, cmp, output_start);
//move output iterator
std::advance(output_start, std::distance(start, mid + 1));
//sort the second half within a recursion
ms_split(output_vec, mid + 1, end, cmp, output_start);
//merge everything together starting from the complete beginning
merge(start, mid, end, cmp, begin);
}
} }
while (start2 <= end) { public:
*output_start = *start2; template<typename Iterator, typename Comparator>
start2++; static auto sort(Iterator start, Iterator end, Comparator cmp) -> void {
output_start++; using valtype = typename std::iterator_traits<Iterator>::value_type;
std::vector<valtype> temporary_dataset(std::distance(start, end));
ms_split(temporary_dataset, start, end - 1, cmp, temporary_dataset.begin());
} }
};
const auto size = std::distance(start_m, end);
for (auto i = 0; i <= size; i++, start_m++, begin++) {
*start_m = *begin;
}
}
template<typename Container, typename Iterator, typename Comparator>
void ms_split(Container &output_vec, Iterator start, Iterator end, Comparator cmp, Iterator output_start) {
Iterator mid = start;
Iterator begin = output_start;
if (std::distance(start, end) < 1) {
return;
} else {
//move mid iterator litterally to the mid
std::advance(mid, std::distance(start, end) / 2);
//sort the first half within an recursion
ms_split(output_vec, start, mid, cmp, output_start);
//move output iterator
std::advance(output_start, std::distance(start, mid + 1));
//sort the second half within a recursion
ms_split(output_vec, mid + 1, end, cmp, output_start);
//merge everything together starting from the complete beginning
merge(start, mid, end, cmp, begin);
}
}
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> temporary_dataset(std::distance(start, end));
ms_split(temporary_dataset, start, end - 1, cmp, temporary_dataset.begin());
}
} }