我正在尝试一步一步地遵循此代码,但仍然无法理解它正在采取的某些步骤。
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);
}
这是一个简单的例子,您可以看到问题所在。它正在对整数数组{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");
}
这是输出。
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
令我困惑的是:
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
我希望有一个+ m可以将一个地址从0xbfadcebc更改为其他地方,但它只会再次产生数字4作为输出。这就好像合并(a + m,n-m)没有任何效果,产生的效果就像我写了合并(a,n-m)一样。
此外,merge(a,n,m)不是递归函数,所以我只希望函数在运行后结束。 我不明白这个:
a after merge_sort(a,m) 0xbfadcebc
m 2
n 4
3
4
...可以是合并后的下一步(a,n,m)。
答案 0 :(得分:0)
评论代码:
/* 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 */
}