Last active
December 31, 2018 19:31
-
-
Save PanagiotisPtr/4510a094be1e9872be9533dcc504f23c to your computer and use it in GitHub Desktop.
parallel and serialized versions of mergesort in C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef SORT_H | |
#define SORT_H | |
#include <algorithm> | |
#include <list> | |
#include <iterator> | |
#include <future> | |
#include <iostream> | |
namespace Palgos { | |
static const size_t CHUCK_SIZE = 100000; | |
class Sort { | |
public: | |
template< | |
typename RandomIt, | |
typename Compare = std::less<typename std::iterator_traits<RandomIt>::value_type> | |
> | |
static void parallel_quick_sort(RandomIt first, RandomIt last, Compare comp = {}){ | |
if(std::distance(first, last) <= CHUCK_SIZE){ | |
quick_sort(first, last, comp); | |
return; | |
} | |
RandomIt pivot = partition(first, last, comp); | |
std::future<void> left( | |
std::async(¶llel_quick_sort<RandomIt, Compare>, first, pivot, comp) | |
); | |
pivot++; | |
parallel_quick_sort(pivot, last, comp); | |
left.get(); | |
} | |
template< | |
typename RandomIt, | |
typename Compare = std::less<typename std::iterator_traits<RandomIt>::value_type> | |
> | |
static void quick_sort(RandomIt first, RandomIt last, Compare comp = {}){ | |
typedef typename std::iterator_traits<RandomIt>::value_type value_type; | |
if(distance(first, last) <= 1) | |
return; | |
// partition | |
RandomIt pivot = partition(first, last, comp); | |
quick_sort(first, pivot, comp); | |
pivot++; | |
quick_sort(pivot, last, comp); | |
} | |
template< | |
typename RandomIt, | |
typename Compare = std::less<typename std::iterator_traits<RandomIt>::value_type> | |
> | |
static void parallel_merge_sort(RandomIt first, RandomIt last, Compare comp = {}){ | |
if(std::distance(first, last) <= CHUCK_SIZE){ | |
merge_sort(first, last, comp); | |
return; | |
} | |
RandomIt mid = first; | |
std::advance(mid, std::distance(first, last)/2); | |
std::future<void> left(std::async(¶llel_merge_sort<RandomIt, Compare>, first, mid, comp)); | |
parallel_merge_sort(mid, last, comp); | |
left.get(); | |
merge(first, mid, last, comp); | |
} | |
template< | |
typename RandomIt, | |
typename Compare = std::less<typename std::iterator_traits<RandomIt>::value_type> | |
> | |
static void merge_sort(RandomIt first, RandomIt last, Compare comp = {}){ | |
if(std::distance(first, last) <= 1) | |
return; | |
RandomIt mid = first; | |
std::advance(mid, std::distance(first, last)/2); | |
merge_sort(first, mid, comp); | |
merge_sort(mid, last, comp); | |
merge(first, mid, last, comp); | |
} | |
private: | |
template< | |
typename RandomIt, | |
typename Compare = std::less<typename std::iterator_traits<RandomIt>::value_type> | |
> | |
static RandomIt partition(RandomIt first, RandomIt last, Compare comp = {}){ | |
RandomIt front = first+1; | |
RandomIt back = first+1; | |
for(front; front != last; front++){ | |
if(comp(*front, *first)){ | |
std::swap(*back, *front); | |
back++; | |
} | |
} | |
back--; | |
std::swap(*first, *back); | |
return back; | |
} | |
template< | |
typename RandomIt, | |
typename Compare = std::less<typename std::iterator_traits<RandomIt>::value_type>, | |
typename Container = std::list<typename std::iterator_traits<RandomIt>::value_type> | |
> | |
static void merge(RandomIt first, RandomIt mid, RandomIt last, Compare comp = {}){ | |
typedef typename std::iterator_traits<RandomIt>::value_type value_type; | |
RandomIt i = first; | |
RandomIt j = mid; | |
Container res; | |
std::back_insert_iterator<Container> it(res); | |
while(i != mid && j != last){ | |
if(comp(*i, *j)) | |
*it++ = *i++; | |
else | |
*it++ = *j++; | |
} | |
while(i != mid) | |
*it++ = *i++; | |
while(j != last) | |
*it++ = *j++; | |
std::copy(std::begin(res), std::end(res), first); | |
} | |
}; | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment