[英]How does the merge() in merge_sort() work?
So I was looking at the C example of merge sort on Rosetta Code and I'm a bit confused about how the merge() function works. 因此,我在查看Rosetta Code上的归类排序的C示例,并对merge()函数的工作方式有些困惑。 I think it is the syntax they use that throws me off with the colons and ?'s.
我认为正是他们使用的语法使我对冒号和?不满意。
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);
}
What exactly is happening in the for loop of the merge() function? 在merge()函数的for循环中到底发生了什么? Can someone explain it please?
有人可以解释吗?
Read the comments: 阅读评论:
void merge (int *a, int n, int m) {
int i, j, k;
// inefficient: allocating a temporary array with malloc
// once per merge phase!
int *x = malloc(n * sizeof (int));
// merging left and right halfs of a into temporary array x
for (i = 0, j = m, k = 0; k < n; k++) {
x[k] = j == n ? a[i++] // right half exhausted, take from left
: i == m ? a[j++] // left half exhausted, take from right
: a[j] < a[i] ? a[j++] // right element smaller, take that
: a[i++]; // otherwise take left element
}
// copy temporary array back to original array.
for (i = 0; i < n; i++) {
a[i] = x[i];
}
free(x); // free temporary array
}
void merge_sort (int *a, int n) {
if (n < 2)
return;
int m = n / 2;
// inefficient: should not recurse if n == 2
// recurse to sort left half
merge_sort(a, m);
// recurse to sort right half
merge_sort(a + m, n - m);
// merge left half and right half in place (via temp array)
merge(a, n, m);
}
A simpler and more efficient version of the merge
function, using only half as much temporary space: merge
功能的更简单,更有效的版本,仅使用一半的临时空间:
static void merge(int *a, int n, int m) {
int i, j, k;
int *x = malloc(m * sizeof (int));
// copy left half to temporary array
for (i = 0; i < m; i++) {
x[i] = a[i];
}
// merge left and right half
for (i = 0, j = m, k = 0; i < m && j < n; k++) {
a[k] = a[j] < x[i] ? a[j++] : x[i++];
}
// finish copying left half
while (i < m) {
a[k++] = x[i++];
}
}
A faster version of merge_sort
involves allocating a temporary array x
of size n * sizeof(*a)
and passing it to a recursive function merge_sort1
that calls merge
with as extra parameter as well. 较快版本的
merge_sort
涉及分配大小为n * sizeof(*a)
的临时数组x
并将其传递给递归函数merge_sort1
,该函数merge_sort1
调用带有merge
额外参数。 The logic in merge
is also improved here with half as many comparisons on i
and j
: merge
的逻辑在这里也得到了改进,对i
和j
进行了一半的比较:
static void merge(int *a, int n, int m, int *x) {
int i, j, k;
for (i = 0; i < m; i++) {
x[i] = a[i];
}
for (i = 0, j = m, k = 0;;) {
if (a[j] < x[i]) {
a[k++] = a[j++];
if (j >= n) break;
} else {
a[k++] = x[i++];
if (i >= m) return;
}
}
while (i < m) {
a[k++] = x[i++];
}
}
static void merge_sort1(int *a, int n, int *x) {
if (n >= 2) {
int m = n / 2;
if (n > 2) {
merge_sort1(a, m, x);
merge_sort1(a + m, n - m, x);
}
merge(a, n, m, x);
}
}
void merge_sort(int *a, int n) {
if (n < 2)
return;
int *x = malloc(n / 2 * sizeof (int));
merge_sort1(a, n, x);
free(x);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.