(Merge sort) The code is printing nothing - c

I recently started learning algorithm with C. I tried to implement merge_sort. But the code is printing nothing and I can't find the problem why this happening. If you take a look at the code and give me the solution it would be very helpful for me. Thanks in advance.
Note: Here I didn't give the main function. Only the merge_sort() and merge() functions
#include <stdio.h>
void merge(int a[], int l[], int r[]);
void merge_sort(int a[], int n) {
if (n < 2) {
return;
} else {
int i;
int mid = (n - 1) / 2;
int l[mid], r[n - mid];
for (i = 0; i < mid; i++) {
l[i] = a[i];
}
for (i = mid; i < n; i++) {
r[i - mid] = a[i];
}
merge_sort(l, mid);
merge_sort(r, n - mid);
merge(a, l, r);
}
}
void merge(int a[], int l[], int r[]) {
int i = 0;
int j = 0;
int k = 0;
int nl = sizeof(l) / sizeof(l[0]);
int nr = sizeof(r) / sizeof(r[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++;
}
}

You cannot compute the size of the arrays passed as parameters with int nl = sizeof(l) / sizeof(l[0]); because sizeof(l) is the size of a pointer to int, not that of the array. sizeof(l) only evaluates to the size of the array when the definition of the array is in scope.
You should pass the sizes explicitly as arguments.
Also change the computation for mid: int mid = n / 2;
Here is a modified version:
#include <stdio.h>
void merge(int a[], int l[], int nl, int r[], int nr);
void merge_sort(int a[], int n) {
if (n < 2) {
return;
} else {
int i;
int mid = n / 2;
int l[mid], r[n - mid];
for (i = 0; i < mid; i++) {
l[i] = a[i];
}
for (i = mid; i < n; i++) {
r[i - mid] = a[i];
}
merge_sort(l, mid);
merge_sort(r, n - mid);
merge(a, l, mid, r, n - mid);
}
}
void merge(int a[], int l[], int nl, int r[], int nr) {
int i = 0;
int j = 0;
int 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++;
}
}

Related

Having issues with outputting the number of searches of a Binary search algorithm

I'm stuck with trying to get the number of searches done within a Binary search algorithm.
The goal is to test how many searches are done depending on how much data is put into the algorithm.
The program in question
//CBinarysearch.c//
#include <stdio.h>
#include <time.h>
#define NUM 100
#define MAX 200
int binary_s(int a[], int n, int s) {
int lo, hi, mid;
int c = 0;
lo = 0;//loの初期化
hi = n-1;//hiの初期化
while (lo <= hi) {
mid = (lo + hi) / 2;//midの初期化
c++;
if (s == a[mid]) break;//探索値がmidと同じ値となればloopを終了
if (s > a[mid])//探索値がmidより大きい場合
lo = mid + 1;//loの値を;1してmidへ移動
else//探索値がmidより小さい場合
hi = mid - 1;//hiの値をー1してmidへ移動
}
if (lo <= hi)
printf("The numerical value %d is in array %d (array element %d)\n", s, mid+1, mid);
else
printf("Could not be located.\n");
return c;
}
void shuffle(int a[]) {
unsigned int i, j;
int tmp;
i = MAX - 1;
while (i > 0) {//シャッフルのためのLoop
j = rand() % (i + 1);//jの値をランダム化
tmp = a[j];
a[j] = a[i];
a[i] = tmp;
i--;
}
}
int quicksort(int a[], int first, int last) {
int i, j, temp, x;
i = first;
j = last;
x = (a[i] + a[j]) / 2;//基準値は平均
while (1) {
while (a[i] < x) i++;
while (a[j] > x) j--;
//iがjより大きくなればwhile loopが解除される
if (i >= j) break;
//a[i]とa[j]を入れ替える
temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
j--;
}
if (first < i-1) quicksort(a, first, i-1);
if (j + 1 < last) quicksort(a, j + 1, last);
return 0;
}
int main(void) {
int a[NUM];
int i;
int count;
int s;
srand((unsigned int)time(NULL));
i = rand() % NUM;
s = a[i];
for (i = 0; i < NUM; i++) {//整列数列の作成
a[i] = i + 1;
}
shuffle(a);//Fisher-Yates shuffle
quicksort(a, 0, NUM-1);//クイックソートの呼び出し
count = binary_s(a, NUM, s);
printf("\n%d ", count);//交換回数の出力
return 0;
}
I've been at this for an embarrassingly long time. And at this point I am adding more details just to make this post viable. It's been rough.
May I ask for some help, please?
You intialize s as s = a[i]; before initializing the array: this has undefined behavior. You should instead write:
s = rand() % NUM + 1;
Furthermore the shuffle function assumes the array has MAX elements whereas you define it with a length of NUM in main(). You should pass the length to shuffle().
Also note that x = (a[i] + a[j]) / 2 would have undefined behavior if the values in the array can be arbitrary large.
You should also consider adding some white space between the code and the comments to make the code more readable, especially to non Japanese readers.
Here is a modified version:
//CBinarysearch.c//
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM 100
int binary_s(int a[], int n, int s) {
int lo, hi, mid;
int c = 0;
lo = 0; // loの初期化
hi = n - 1; // hiの初期化
while (lo <= hi) {
mid = lo + (hi - lo) / 2; // midの初期化
c++;
if (s == a[mid]) // 探索€¤がmidと同じ€¤となればloopを終了
break;
if (s > a[mid]) // 探索€¤がmidより大きい場合
lo = mid + 1; // loの€¤を;1してmidへ移動
else // 探索€¤がmidより小さい場合
hi = mid - 1; // hiの€¤をー1してmidへ移動
}
if (lo <= hi) {
printf("The numerical value %d is in array at index %d\n",
s, lo);
} else {
printf("value %d Could not be located in array.\n", s);
}
return c;
}
void shuffle(int a[], int len) {
int i, j;
int tmp;
for (i = len - 1; i > 0; i--) { // シャッフルのためのLoop
j = rand() % (i + 1); // jの€¤をラン€ム化
tmp = a[j];
a[j] = a[i];
a[i] = tmp;
}
}
void quicksort(int a[], int first, int last) {
int i, j, temp, x;
if (first >= last)
return;
i = first;
j = last;
x = ((long long)a[i] + a[j]) / 2; // 基準€¤は平均
while (1) {
while (a[i] < x) i++;
while (a[j] > x) j--;
//iがjより大きくなればwhile loopが解除される
if (i >= j) break;
//a[i]とa[j]を入れ替える
temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
j--;
}
quicksort(a, first, i - 1);
quicksort(a, j + 1, last);
}
int main(void) {
int a[NUM];
int i;
int count;
int s;
srand((unsigned int)time(NULL));
for (i = 0; i < NUM; i++) { // 整列数列の作成
a[i] = i + 1;
}
s = a[rand() % NUM];
shuffle(a, NUM); // Fisher-Yates shuffle
quicksort(a, 0, NUM - 1); // クイックソートの呼び出し
count = binary_s(a, NUM, s);
printf("iterations: %d\n", count); // 交換回数の出力
return 0;
}

the code of merge_sort doesn`t sort properly

i code the merge sort as below but it doesn't sort the Array. and i cant find the source of the problem.
void print_arr(int Arr[], int size)
{
int i;
for (i = 0;i < size;i++)
printf(" %d ", Arr[i]);
}
///////////////////////////////////////////
void merge(int Arr[], int left, int mid, int right)
{
int i = 0, j = 0, k = left;
int n_l = (mid - left + 1);
int n_r = (right - mid);
int* Arr_l = (int*)calloc(n_l , sizeof(int));
int* Arr_r = (int*)calloc(n_r , sizeof(int));
if (Arr_l == NULL)
return;
if (Arr_r == NULL)
return;
for (i = 0;i < n_l;i++)
Arr_l[i] = Arr[i];
for (j = 0;j < n_r;j++)
Arr_r[j] = Arr[mid + 1 + j];
while (i < n_l && j < n_r)
{
if (Arr_l[i] <= Arr_r[j])
{
Arr[k] = Arr_l[i];
i++;
k++;
}
else
{
Arr[k] = Arr_r[j];
j++;
k++;
}
}
while (i < n_l)
{
Arr[k] = Arr_l[i];
i++;
k++;
}
while (j < n_r)
{
Arr[k] = Arr_r[j];
j++;
k++;
}
free(Arr_l);
free(Arr_r);
}
////////////////////////////////////////////////////////////////////
void merge_sort_inc(int Arr[], int left, int right)
{
int mid = (int)((left + (right - 1)) / 2);
if (left < right)
{
merge_sort_inc(Arr, left, mid);
merge_sort_inc(Arr, mid + 1, right - 1);
merge(Arr, left, mid, right);
}
}
////////////////////////////////////////////////////////////////
int main()
{
int i;
time_t t;
srand((unsigned)time(&t));
int Array[10];
int size = sizeof(Array) / sizeof(int);
for (i = 0;i < size;i++)
Array[i] = rand() / 100;
printf(" The unsorted Arrar is : \n\n");
print_arr(Array, size);
printf("\n\n The sorted Array is : \n ");
merge_sort_inc(Array, 0, size);
print_arr(Array, size);
return 0;
}
int i = 0, j = 0, k = left;
you should reset the value of i, j before while loop
i = 0; j = 0; k = left;
while (i < n_l && j < n_r)
{...}
Then:
for (i = 0;i < n_l;i++)
Arr_l[i] = Arr[i];
change to
for (i = 0;i < n_l;i++)
Arr_l[i] = Arr[left+i];
Finally, the merge_sort_inc function should change to:
void merge_sort_inc(int Arr[], int left, int right) {
if (left < right)
{
int mid = left + (right - left) / 2;
merge_sort_inc(Arr, left, mid);
merge_sort_inc(Arr, mid + 1, right);
merge(Arr, left, mid, right);
}
}
Then in main function, when you call merge_sort_inc function in main:
merge_sort_inc(Array, 0, size-1); // change size to size-1
OT, your part of code below is not wrong:
while (i < n_l)
{
Arr[k] = Arr_l[i];
i++;
k++;
}
while (j < n_r)
{
Arr[k] = Arr_r[j];
j++;
k++;
}
But you can bring k++ to the end of condition to limit one line of code as:
while (i < n_l)
{
Arr[k] = Arr_l[i];
i++;
}
while (j < n_r)
{
Arr[k] = Arr_r[j];
j++;
}
k++;
The complete code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void print_arr(int Arr[], int size)
{
int i;
for (i = 0;i < size;i++)
printf(" %d ", Arr[i]);
}
void merge(int Arr[], int left, int mid, int right)
{
int i, j, k;
int n_l = (mid - left + 1);
int n_r = (right - mid);
int* Arr_l = calloc(n_l , sizeof(int));
int* Arr_r = calloc(n_r , sizeof(int));
if (Arr_l == NULL)
return;
if (Arr_r == NULL)
return;
for (i = 0;i < n_l;i++)
Arr_l[i] = Arr[left+i];
for (j = 0;j < n_r;j++)
Arr_r[j] = Arr[mid + 1 + j];
i = 0; j = 0; k = left;
while (i < n_l && j < n_r)
{
if (Arr_l[i] <= Arr_r[j])
{
Arr[k] = Arr_l[i];
i++;
}
else
{
Arr[k] = Arr_r[j];
j++;
}
k++;
}
while (i < n_l)
{
Arr[k] = Arr_l[i];
i++;
k++;
}
while (j < n_r)
{
Arr[k] = Arr_r[j];
j++;
k++;
}
free(Arr_l);
free(Arr_r);
}
void merge_sort_inc(int Arr[], int left, int right) {
if (left < right)
{
int mid = left + (right - left) / 2;
merge_sort_inc(Arr, left, mid);
merge_sort_inc(Arr, mid + 1, right);
merge(Arr, left, mid, right);
}
}
int main()
{
int i;
time_t t;
srand((unsigned)time(&t));
int Array[10];
int size = sizeof(Array) / sizeof(int);
for (i = 0;i < size;i++)
Array[i] = rand() % 100; // should use % instead of / to have smaller value to see easily
printf(" The unsorted Arrar is : \n\n");
print_arr(Array, size);
printf("\n\n The sorted Array is : \n ");
merge_sort_inc(Array, 0, size-1);
print_arr(Array, size);
return 0;
}
The output of test:
The unsorted Arrar is :
60 32 71 35 93 91 29 80 78 47
The sorted Array is :
29 32 35 47 60 71 78 80 91 93

Program crashes when given a big number

I'm trying to make a merge sort algorithm in C. The problem is that it does not work for a big number of elements. If the array has 100000 elements it's OK but if it has 1e6 or 1e7 then it crashes. I thought that you cannot give such a big number of elements for an array but after I have read that this is not true, you should be able to give 1e7 elements. After that I thought that maybe int range is to small but that's not the case, int goes to 1e9. I don't really know what's the problem and why it doesn't work, so please help. Thanks in advance!
#include <stdio.h>
#include <stdlib.h>
int n;
void merge(int *, int, int);
void mergeSort(int *, int, int);
void bubbleSort(int *, int);
int main() {
// scanf("%d",&n);
n = 10000000;
int *a = (int *)malloc(n * sizeof(int));
if (a == NULL) {
printf("Nu s-a putut aloca memorie.");
exit(0);
}
for (int i = 0; i < n; i++)
a[i] = rand() % 50;
mergeSort(a, 0, n - 1);
//bubbleSort(a, n - 1);
// for (int i = 0; i < n; i++) {
// printf("%d ", a[i]);
// }
free(a);
return 0;
}
void merge(int *a, int start, int sfarsit) {
int mij = (start + sfarsit) / 2;
int i = start;
int j = mij + 1;
int k = start;
int aux[10000000];
while (i <= mij && j <= sfarsit) {
if (a[i] < a[j])
aux[k++] = a[i++];
else
aux[k++] = a[j++];
}
while (i <= mij)
aux[k++] = a[i++];
while (j <= sfarsit)
aux[k++] = a[j++];
for (int i = start; i <= sfarsit; i++)
a[i] = aux[i];
}
void mergeSort(int *a, int start, int sfarsit) {
if (start >= sfarsit)
return ;
int mij = (start + sfarsit) / 2;
mergeSort(a, start, mij);
mergeSort(a, mij + 1, sfarsit);
merge(a, start, sfarsit);
}
This:
int aux[10000000];
is problem. That will be to much for the stack to handle. Change to this:
int *aux = malloc(sizeof(*aux) * 10000000);
Of course, you need to use free(aux) in the end of the function merge and also check if the allocation was successful.
Also, you should of course allocate in relation to sfarsit but judging from your other code, it does not seem like I need to tell you that.
Your program has this problem: the definition int aux[10000000]; in the merge function defines a temporary array with automatic storage (aka on the stack) which is:
very large, potentially too large for your system, causing a stack overflow.
not necessary large enough if the array to be sorted is larger than 10 million elements.
You should allocate this temporary array, either locally in merge or in a wrapper function that would call mergesort with an extra argument.
It is also unnecessary and quite error prone to make n a global variable.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
int mergeSort(int *a, int length);
void bubbleSort(int *, int);
int main() {
int n;
int *a;
n = 10000000;
//scanf("%d", &n);
if ((a = malloc(sizeof(*a) * n)) == NULL) {
printf("Nu s-a putut aloca memorie.");
return 1;
}
for (int i = 0; i < n; i++)
a[i] = rand() % 50;
mergeSort(a, n);
//bubbleSort(a, n);
for (int i = 1; i < n; i++) {
if (a[i] < a[i - 1]) {
printf("mergeSort failed\n");
break;
}
}
free(a);
return 0;
}
void merge(int *a, int start, int mij, int sfarsit, int *aux) {
int i = start;
int j = mij + 1;
int k = start;
while (i <= mij && j <= sfarsit) {
if (a[i] <= a[j])
aux[k++] = a[i++];
else
aux[k++] = a[j++];
}
while (i <= mij)
aux[k++] = a[i++];
while (j <= sfarsit)
aux[k++] = a[j++];
for (i = start; i <= sfarsit; i++)
a[i] = aux[i];
}
void mergeSortAux(int *a, int start, int sfarsit, int *aux) {
if (start >= sfarsit)
return;
int mij = (start + sfarsit) / 2;
mergeSortAux(a, start, mij, aux);
mergeSortAux(a, mij + 1, sfarsit, aux);
merge(a, start, mij, sfarsit, aux);
}
int mergeSort(int *a, int length) {
if (length > 1) {
int *aux = malloc(sizeof(*aux) * length);
if (aux == NULL)
return -1;
mergeSortAux(a, 0, length - 1, aux);
free(aux);
}
return 0;
}
Note that you can improve this code:
using size_t instead of int for the array sizes and index variables
using the convention start included and stop excluded, which avoids the +1/-1 adjustments.
by not copying the remaining values from the right slice as they are already in place in the original array.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
int mergeSort(int *a, size_t length);
int main(int argc, char *argv[]) {
size_t n = 10000000;
int *a;
int res = 0;
if (argc > 1) {
n = strtoll(argv[1], NULL, 0);
}
if ((a = malloc(sizeof(*a) * n)) == NULL) {
printf("Nu s-a putut aloca memorie.");
return 1;
}
for (size_t i = 0; i < n; i++) {
a[i] = rand() % 50;
}
if (mergeSort(a, n)) {
printf("mergeSort failed: allocation error\n");
res = 1;
} else {
for (size_t i = 1; i < n; i++) {
if (a[i] < a[i - 1]) {
printf("mergeSort failed: out of order\n");
res = 1;
break;
}
}
}
free(a);
return res;
}
void merge(int *a, size_t start, size_t mid, size_t stop, int *aux) {
size_t i = start;
size_t j = mid;
size_t k = start;
while (i < mid && j < stop) {
if (a[i] <= a[j])
aux[k++] = a[i++];
else
aux[k++] = a[j++];
}
while (i < mid)
aux[k++] = a[i++];
for (i = start; i < k; i++)
a[i] = aux[i];
}
void mergeSortAux(int *a, size_t start, size_t stop, int *aux) {
if (stop - start >= 2) {
size_t mid = start + (stop - start) / 2;
mergeSortAux(a, start, mid, aux);
mergeSortAux(a, mid, stop, aux);
merge(a, start, mid, stop, aux);
}
}
int mergeSort(int *a, size_t length) {
if (length > 1) {
int *aux = malloc(sizeof(*aux) * length);
if (aux == NULL)
return -1;
mergeSortAux(a, 0, length, aux);
free(aux);
}
return 0;
}

Mergesort bug + warnings

I have the following code, followed it form a tutorial, and it doesn't seem to do anything. I tried debugging it with KDB but I can't find the problem why it doesn't sort.
Maybe someone on here can help me, thanks in advance!
#include <stdio.h>
#include <stdlib.h>
void Mergesort(int *a, int length) {
int i = 0;
int mid = 0;
int *L, *R;
mid = length / 2;
if (length < 2)
return;
else {
L = (int*)malloc(sizeof(int) * mid);
R = (int*)malloc(sizeof(int) * (length - mid));
for (i = 0; i < mid; i++) {
L[i] = a[i];
}
for (i = mid; i < length; i++) {
R[i - mid] = a[i];
}
Mergesort(L, mid);
Mergesort(R, length - mid);
Merge(a, L, R, length);
}
}
void Merge(int *a, int *L, int *R, int length) {
int i = 0, j = 0, k = 0;
int mL, mR;
mL = length / 2;
mR = length - mL;
while (i < mL && j < mR) {
if (L[i] < R[j]) {
a[k] = L[i];
i++;
} else {
a[k] = R[j];
j++;
}
k++;
}
while (i < mL) {
a[k] = L[i];
i++;
k++;
}
while (j < mR) {
a[k] = R[j];
i++;
k++;
}
}
void main() {
int a[7] = { 5, 4, 99, 13, 34, 54, 2 };
int u = 0;
Mergesort(a, 7); // call to Mergesort
for (u = 0; u < 7; u++) {
printf(" %d\t", a[u]);
}
printf("\n\n\n");
}
I would really appreciate it since I need to understand it before Thursday next week :P
Here you're incrementing i but you should increment j in Merge function.
while(j<mR)
{
a[k]=R[j];
j++;
k++;
}
Edit:
put function declation after the header files void Merge(int *a,int *L,int *R,int length); otherwise you will get implicit declaration of function ‘Merge’ warning.
#include<stdio.h>
#include<stdlib.h>
void Merge(int *a,int *L,int *R,int length);
//rest of your code

Merge sort algorithm in C not working as expected

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?
A more nearly idiomatic way of writing the merge() code would be:
void merge(int a[], int L[], int R[],int nL, int nR)
{
int i = 0, j = 0, k = 0;
while (i < nL && j < nR)
{
if (L[i] <= R[j])
a[k++] = L[i++];
else
a[k++] = R[j++];
}
while (i < nL)
a[k++] = L[i++];
while (j < nR)
a[k++] = R[j++];
}
That's about half the number of lines of your code, and within broad limits, the less code there is to read, the better. There are those who insist on having braces after each loop or conditional. I don't think that's necessary (or particularly helpful), but if that's the style you like, you can use it.
Your mergesort() code is less flabby, but could be changed to:
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; i++)
right[i-mid] = a[i];
mergesort(left, mid);
mergesort(right, n - mid);
merge(a, left, right, mid, n - mid);
}
This includes the fix for your main problem — the loop loading the right array was leaving the last element uncopied.
With a debugging function such as:
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');
}
You can do a lot of effective debugging with:
void mergesort(int a[],int n)
{
if (n < 2)
return;
int mid = n / 2;
int left[mid];
int right[n-mid];
dump_array("-->>mergesort()", n, a);
for (int i = 0; i < mid; i++)
left[i] = a[i];
dump_array("left", mid, left);
for (int i = mid; i < n; i++)
right[i-mid] = a[i];
dump_array("right", n - mid, right);
mergesort(left, mid);
dump_array("merged-L", mid, left);
mergesort(right, n - mid);
dump_array("merged-R", n - mid, right);
merge(a, left, right, mid, n - mid);
dump_array("<<--mergesort()", n, a);
}
In your code, the output with the tag right would show 0 or semi-random data for the last element, rather than what you're expecting. This would be a hint as to where the trouble is. Keep the dump_array() function around; it is a useful creature to have. It's a simple-minded version; you can invent more complex versions which outputs a newline at intermediate positions for long arrays, for example.
The issue is in the following code:
for(int i = mid; i < n-1; i++)
{
right[i-mid] = a[i];
}
It should be:
for(int i = mid; i < n; i++) // right should range from mid to n - 1 *inclusive*
{
right[i-mid] = a[i];
}
This is simple implementation of merge sort without any complications. Just pass the array pointer and total number of entires in the array.
void merge(int *a, int top)// Array pointer and max entries
{
int l1, k, l2, u1, u2, size = 1, i, j;
int *sa;
sa = (int *)calloc(top, sizeof(int));
while (size < top)
{
l1 = 0;
k = 0;
while (l1 + size < top)
{
l2 = l1 + size;
u1 = l2 - 1;
u2 = ((l2 + size - 1) < top ? l2 + size - 1 : top - 1);
for (i = l1, j = l2; i <= u1 && j <= u2; )// Merging
{
sa[k++] = a[i] <= a[j] ? a[i++] : a[j++];
}
for ( ; i <= u1; )
sa[k++] = a[i++];
for ( ; j <= u2; )
sa[k++] = a[j++];
l1 = u2 + 1;
}
for (i = l1; i < top; i++) // For the left outs of the process
sa[k++] = a[i];
for (i = 0; i < top; i++)
a[i] = sa[i];
size *= 2;
}
}

Resources