I have written a merge sort in C and would like any advice on how to improve it. Any advice helps to make the code better!
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
static void mergesort_helper(void *array, uint32_t index, uint32_t length, size_t size_element, int32_t compare(void *, void *), void *storage)
{
uint32_t i, j, k;
if(length == 1)
{
/*printf("\n%d, %d\n", index, length);*/
return;
}
mergesort_helper(array, index, length / 2, size_element, compare, storage);
if(length % 2 == 0)
mergesort_helper(array, (index + (index + length)) / 2, length / 2, size_element, compare, storage);
else
mergesort_helper(array, (index + (index + length)) / 2, length / 2 + 1, size_element, compare, storage);
/*sorting part*/
i = index;
j = (index + (index + length)) / 2;
k = 0;
while(i < (index + (index + length)) / 2 || j < (index + length))
{
if(i < (index + (index + length)) / 2 && (compare(array + i * size_element, array + j * size_element) <= 0 || j >= (index + length)))
{
memcpy(storage + k * size_element, array + i * size_element, size_element);
i++;
}
else if(j < (index + length) && (compare(array + i * size_element, array + j * size_element) > 0) || i >= (index + (index + length)) / 2)
{
memcpy(storage + k * size_element, array + j * size_element, size_element);
j++;
}
k++;
}
memcpy(array + index * size_element, storage, length * size_element);
}
/*
array - to be sorted
length - exclusive
size_element - how big is one element
*/
void mergesort(void *array, uint32_t length, size_t size_element, int32_t compare(void *, void *))
{
void *storage;
if(length == 0)
return;
storage = malloc(size_element * length);
mergesort_helper(array, 0, length, size_element, compare, storage);
free(storage);
}
/*user code*/
int32_t compare(void *ptr1, void *ptr2)
{
int32_t *temp_ptr1, *temp_ptr2;
temp_ptr1 = (int32_t *)ptr1;
temp_ptr2 = (int32_t *)ptr2;
if(*temp_ptr1 < *temp_ptr2)
return -1;
else if(*temp_ptr1 > *temp_ptr2)
return 1;
return 0;
}
int main(void)
{
uint32_t i;
int32_t array[] = {6, 4, 3, 2, 7, -100, 1, 0, 5, 8, -100, 8};
for(i = 0; i < sizeof(array) / sizeof(array[0]); i++)
{
printf("%d ", array[i]);
}
printf("\n");
mergesort(array, sizeof(array) / sizeof(array[0]), sizeof(array[0]), &compare);
for(i = 0; i < sizeof(array) / sizeof(array[0]); i++)
{
printf("%d ", array[i]);
}
printf("\n");
return 0;
}
qsort
function which is already in the standard C library. Yourmergesort
function has almost identical conventions toqsort
(except for the missingconst
on the comparison function's parameters) which is probably no coincidence. The only drawback ofqsort
is that it's not required to be a stable sort. \$\endgroup\$cmp
andmemmove
, at which point it's fairly easy to write a merge sort that'll beatqsort
by a decent margin. (Although a handwritten quicksort with random pivot would presumably do even better, on average.) \$\endgroup\$