I am learning programming online and currently watching CS50 lectures, in third lecture, professor introduces us to merge_sort though only through pseudo code, so I wanted someone to review my implementation and tell me where I can improve and what I possibly missed.
#include <algorithm>
#include <assert.h>
#include <cmath>
#include <iostream>
#include <vector>
template <typename T> void merge_sort(T m_array[], const size_t size) {
using namespace std;
if (size < 2)
return;
else if (size == 2) {
if (m_array[0] > m_array[1])
std::swap(m_array[0], m_array[1]); // no need for a new array
return;
}
merge_sort(m_array, size / 2);
merge_sort(m_array + size / 2,
std::ceil(static_cast<double>(size) /
2) // for odd size, divison will have truncated value
// and recursion will left the the last array value
// for sorting, size%2==0?size/2:size/2+1
);
T *new_array = new T[size];
size_t na_pos = 0;
const T *array1 = m_array, *array2 = m_array + size / 2;
const T *const array1end = m_array + size / 2, *const array2end =
m_array + size;
while (1) {
if (array1 == array1end)
break;
if (array2 == array2end)
break;
if (*array1 < *array2)
new_array[na_pos++] = *array1++;
else if (*array2 < *array1)
new_array[na_pos++] = *array2++;
else if (*array1 == *array2) {
new_array[na_pos++] = *array1++;
new_array[na_pos++] = *array2++;
}
}
assert(array1 == array1end || array2 == array2end);
while (array1 != array1end)
new_array[na_pos++] = *array1++;
while (array2 != array2end)
new_array[na_pos++] = *array2++;
assert(na_pos == size);
for (na_pos = 0; na_pos < size; na_pos++)
m_array[na_pos] = new_array[na_pos];
delete[] new_array;
}
int main() {
using namespace std;
auto limit = 10000;
const auto size = 21;
while (limit--) {
vector<int> a;
a.reserve(size);
while (a.size() < size)
a.push_back(rand() % 10000);
merge_sort(a.data(), a.size());
assert(std::is_sorted(a.begin(), a.end()));
}
return 0;
}