I am trying to implement the merge sort algorithm in C. I understand how the algorithm is supposed to work however I am encountering some difficulties with the implementation.
I understand that there are hundreds of examples and source code for it's implementation but I was hoping someone could help me understand why mine is not working correctly.
My code is below and after the code I explain what I have tried so far.
#include <stdio.h>
void merge(int a[], int L[], int R[],int nL, int nR) //nL and nR are the lengths of L[] and R[]
{
int i = 0 , j = 0, k = 0;
while(i<nL && j <nR)
{
if(L[i] <= R[j]){
a[k] = L[i];
i++;
}
else{
a[k] = R[j];
j++;
}
k++;
}
while(i < nL){
a[k] = L[i];
i++;
k++;
}
while(j < nR) {
a[k] = R[j];
j++;
k++;
}
}
void mergesort(int a[],int n) //n is the length of a[]
{
if(n < 2) return; //BASE CASE
int mid = n / 2;
int left[mid];
int right[n-mid];
for(int i = 0; i < mid; i++)
{
left[i] = a[i];
}
for(int i = mid; i < n-1; i++)
{
right[i-mid] = a[i];
}
int nL = sizeof(left) / sizeof(left[0]);
int nR = sizeof(right) / sizeof(right[0]);
mergesort(left, nL);
mergesort(right, nR);
merge(a,left,right,nL,nR);
}
int main(void)
{
printf("Initial:\n");
printf("3 4 1 6\n");
int numbers[4] = {3,4,1,6};
int n = sizeof(numbers) / sizeof(int);
mergesort(numbers,n);
printf("Sorted:\n");
for(int i =0 ; i < 4; i++)
{
printf("%d ", numbers[i]);
}
return 0;
}
As it is and with the unsorted array [3,4,1,6] the output is 0 0 1 3.
Clearly the 1 and 3 are in the right order relative to each other but the two zeros at the beginning are clearly wrong. At first it seemed to me that I was inserting 4 and 6 to the right and out of bounds of the array.
I used some print statements to try and debug but I haven't been able to figure out what was going on. I even tried to follow my code with gdb but I still could not sort it.
Does any one have any ideas of what might be happening?
sizeof()calculations. You already know the length of each subsequence :midandn-mid. What is more likely the problem, assuming yourmerge()algorithm is correct (a big assumption) your right-side copy isn't correct. It should run toi < n, noti < n-1.-1infor(int i = mid; i < n-1; i++)is unwanted. For the rest, debug by providing yourself with a functionvoid dump_array(const char *tag, int n, int *a) { printf("%d:", n); for (int i = 0; i < n; i++) printf("%s:%d:", a[i]); putchar('\n'); }and call it frequently: on entry tomergesort()(dump_array("enter", n, a);), after you've created the left array, after you've created the right array, after you've merge sorted the left array, after you've merge sorted the right array, after you've merged the result. It will help you narrow down the problems.void dump_array(const char *tag, int n, int *a) { printf("%s:%d:", tag, n); for (int i = 0; i < n; i++) printf(" %3d", a[i]); putchar('\n'); }and call it frequently: on entry tomergesort()(for example,dump_array("-->>mergesort()", n, a);), after creating the left array, after creating the right array, after merge sorting the left array, after merge sorting the right array, after merging the result (dump_array("<<--mergesort()", n, a);). It will help you narrow down the problems.