#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
using namespace std;
// general mergesort algorithm
template <typename Iterator>
void mergesort(Iterator first, Iterator last)
{
typedef typename std::iterator_traits<Iterator>::value_type value_type;
size_t d = std::distance(first, last);
size_t n = d/2;
if (n == 0)
return;
// invoke recursion on the submerges
if (n > 1)
mergesort(first, first + n);
if (d > 1)
mergesort(first + n, last);
// create merge-buffer
std::vector<value_type> mrg;
mrg.reserve(d);
// and merge into it.
std::merge(first, first+n, first+n, last, back_inserter(mrg));
std::copy(mrg.begin(), mrg.end(), first);
}
// front-loader for static arrays
template<typename Item, size_t N>
void mergesort(Item (&ar)[N])
{
mergesort(std::begin(ar), std::end(ar));
}
int main()
{
srand((unsigned)time(0));
vector<int> data;
// fill a vector with random junk.
generate_n(back_inserter(data), 15, []() { return std::rand() % 99+1;});
copy(data.begin(), data.end(), ostream_iterator<int>(cout, " "));
cout << endl;
mergesort(data.begin(), data.end());
copy(data.begin(), data.end(), ostream_iterator<int>(cout, " "));
cout << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aXRlcmF0b3I+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDx2ZWN0b3I+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgovLyBnZW5lcmFsIG1lcmdlc29ydCBhbGdvcml0aG0KdGVtcGxhdGUgPHR5cGVuYW1lIEl0ZXJhdG9yPgp2b2lkIG1lcmdlc29ydChJdGVyYXRvciBmaXJzdCwgSXRlcmF0b3IgbGFzdCkKewogICAgdHlwZWRlZiB0eXBlbmFtZSBzdGQ6Oml0ZXJhdG9yX3RyYWl0czxJdGVyYXRvcj46OnZhbHVlX3R5cGUgdmFsdWVfdHlwZTsKCiAgICBzaXplX3QgZCA9IHN0ZDo6ZGlzdGFuY2UoZmlyc3QsIGxhc3QpOwogICAgc2l6ZV90IG4gPSBkLzI7CiAgICBpZiAobiA9PSAwKQogICAgICAgIHJldHVybjsKICAgIAogICAgLy8gaW52b2tlIHJlY3Vyc2lvbiBvbiB0aGUgc3VibWVyZ2VzCiAgICBpZiAobiA+IDEpCiAgICAgICAgbWVyZ2Vzb3J0KGZpcnN0LCBmaXJzdCArIG4pOwogICAgaWYgKGQgPiAxKQogICAgICAgIG1lcmdlc29ydChmaXJzdCArIG4sIGxhc3QpOwogICAgCiAgICAvLyBjcmVhdGUgbWVyZ2UtYnVmZmVyCiAgICBzdGQ6OnZlY3Rvcjx2YWx1ZV90eXBlPiBtcmc7CiAgICBtcmcucmVzZXJ2ZShkKTsKICAgIAogICAgLy8gYW5kIG1lcmdlIGludG8gaXQuCiAgICBzdGQ6Om1lcmdlKGZpcnN0LCBmaXJzdCtuLCBmaXJzdCtuLCBsYXN0LCBiYWNrX2luc2VydGVyKG1yZykpOwogICAgc3RkOjpjb3B5KG1yZy5iZWdpbigpLCBtcmcuZW5kKCksIGZpcnN0KTsKfQoKLy8gZnJvbnQtbG9hZGVyIGZvciBzdGF0aWMgYXJyYXlzCnRlbXBsYXRlPHR5cGVuYW1lIEl0ZW0sIHNpemVfdCBOPgp2b2lkIG1lcmdlc29ydChJdGVtICgmYXIpW05dKQp7CiAgICBtZXJnZXNvcnQoc3RkOjpiZWdpbihhciksIHN0ZDo6ZW5kKGFyKSk7Cn0KCmludCBtYWluKCkKewogICAgc3JhbmQoKHVuc2lnbmVkKXRpbWUoMCkpOwogICAgdmVjdG9yPGludD4gZGF0YTsKCiAgICAvLyBmaWxsIGEgdmVjdG9yIHdpdGggcmFuZG9tIGp1bmsuCiAgICBnZW5lcmF0ZV9uKGJhY2tfaW5zZXJ0ZXIoZGF0YSksIDE1LCBbXSgpIHsgcmV0dXJuIHN0ZDo6cmFuZCgpICUgOTkrMTt9KTsKICAgIGNvcHkoZGF0YS5iZWdpbigpLCBkYXRhLmVuZCgpLCBvc3RyZWFtX2l0ZXJhdG9yPGludD4oY291dCwgIiAiKSk7CiAgICBjb3V0IDw8IGVuZGw7CiAgICAKICAgIG1lcmdlc29ydChkYXRhLmJlZ2luKCksIGRhdGEuZW5kKCkpOwogICAgY29weShkYXRhLmJlZ2luKCksIGRhdGEuZW5kKCksIG9zdHJlYW1faXRlcmF0b3I8aW50Pihjb3V0LCAiICIpKTsKICAgIGNvdXQgPDwgZW5kbDsKICAgIHJldHVybiAwOwp9