Reputation: 902
I'm trying to follow this code step by step but still I can't understand certain steps it's taking.
void merge (int *a, int n, int m) {
int i, j, k;
int *x = malloc(n * sizeof (int));
for (i = 0, j = m, k = 0; k < n; k++) {
x[k] = j == n ? a[i++]
: i == m ? a[j++]
: a[j] < a[i] ? a[j++]
: a[i++];
}
for (i = 0; i < n; i++) {
a[i] = x[i];
}
free(x);
}
void merge_sort (int *a, int n) {
if (n < 2)
return;
int m = n / 2;
merge_sort(a, m);
merge_sort(a + m, n - m);
merge(a, n, m);
}
Here's a simple example so that you can see what the issues are. It's sorting the integer array {4,3,2,1} .
#include <stdio.h>
#include <stdlib.h>
void merge (int *a, int n, int m) {
int i, j, k;
int *x = malloc(n * sizeof (int));
for (i = 0, j = m, k = 0; k < n; k++) {
x[k] = j == n ? a[i++]
: i == m ? a[j++]
: a[j] < a[i] ? a[j++]
: a[i++];
}
for (i = 0; i < n; i++) {
a[i] = x[i];
}
free(x);
}
void merge_sort (int *a, int n) {
if (n < 2)
return;
int m = n / 2;
int g;
printf("a before merge_sort(a,m) %i\n",a);
printf("m %i\n",m);
printf("n %i\n",n);
printf("\n");
for(g=0;g<m;++g) printf("%i\n", a[g]);
merge_sort(a, m);
printf("a after merge_sort(a,m) %i\n",a);
printf("m %i\n",m);
printf("n %i\n",n);
printf("\n");
for(g=0;g<m;++g) printf("%i\n", a[g]);
merge_sort(a + m, n - m);
printf("a after merge_sort(a+m, n-m) %i\n",a);
printf("m %i\n",m);
printf("n %i\n",n);
printf("\n");
for(g=0;g<m;++g) printf("%i\n",a[g]);
merge(a, n, m);
printf("a after merge(a,n,m) %i\n ",a);
printf("m %i\n",m);
printf("n %i\n",n);
for(g=0;g<m;++g) printf("%i\n",a[g]);
}
int main(){
int test[4] = {4,3,2,1};
int i;
merge_sort(&test[0],4);
printf("\nFinal result:\n");
for(i=0;i<4;++i){
printf("%i ",test[i]);
}
printf("\n");
}
And here's the output.
Begin of if
End of if(no return)
a before merge_sort(a,m) 0xbfadcebc
m 2
n 4
4
3
Begin of if
End of if(no return)
a before merge_sort(a,m) 0xbfadcebc
m 1
n 2
4
Begin of if
a after merge_sort(a,m) 0xbfadcebc
m 1
n 2
4
Begin of if
a after merge_sort(a+m, n-m) 0xbfadcebc
m 1
n 2
4
a after merge(a,n,m) 0xbfadcebc
m 1
n 2
3
a after merge_sort(a,m) 0xbfadcebc
m 2
n 4
3
4
Begin of if
End of if(no return)
a before merge_sort(a,m) 0xbfadcec4
m 1
n 2
2
Begin of if
a after merge_sort(a,m) 0xbfadcec4
m 1
n 2
2
Begin of if
a after merge_sort(a+m, n-m) 0xbfadcec4
m 1
n 2
2
a after merge(a,n,m) 0xbfadcec4
m 1
n 2
1
a after merge_sort(a+m, n-m) 0xbfadcebc
m 2
n 4
3
4
a after merge(a,n,m) 0xbfadcebc
m 2
n 4
1
2
Final result:
1 2 3 4
This is what's puzzling me:
Begin of if
a after merge_sort(a+m, n-m) 0xbfadcebc
m 1
n 2
4
a after merge(a,n,m) 0xbfadcebc
m 1
n 2
3
I'd expect a+m to change the address of a from 0xbfadcebc to something else, but it simply produces the number 4 as an output again. It's as if merge(a+m,n-m) didn't have any effect and produced the same as if I had written merge(a,n-m).
Furthermore, merge(a,n,m) is not a recursive function, so I'd just expect the function to end after running it. I don't get how this:
a after merge_sort(a,m) 0xbfadcebc
m 2
n 4
3
4
...can be the next step after merge(a,n,m).
Upvotes: 0
Views: 87
Reputation: 28828
Commented code:
/* a = ptr to sub-array */
/* 0 = starting index */
/* m = mid point index */
/* n = ending index */
/* left half indices = 0 to m-1 */
/* right half indices = m to n */
void merge (int *a, int n, int m) {
int i, j, k;
int *x = malloc(n * sizeof (int)); /* allocate temp array */
for (i = 0, j = m, k = 0; k < n; k++) {
x[k] = j == n ? a[i++] /* if end of right, copy left */
: i == m ? a[j++] /* if end of left, copy right */
: a[j] < a[i] ? a[j++] /* if right < left, copy right */
: a[i++]; /* else (left <= right), copy left */
}
for (i = 0; i < n; i++) { /* copy x[] back into a[] */
a[i] = x[i];
}
free(x); /* free temp array */
}
/* a = ptr to sub-array */
/* n = size == ending index of sub-array */
void merge_sort (int *a, int n) {
if (n < 2) /* if < 2 elements nothing to do */
return;
int m = n / 2; /* m = mid point index */
merge_sort(a, m); /* sort a[0] to a[m-1] */
merge_sort(a + m, n - m); /* sort a[m] to a[n-1] */
merge(a, n, m); /* merge the two halves */
}
Upvotes: 1