我不明白我的代码中的问题。我得到我的算法的书是:算法简介,第三版
我知道算法是如何工作的,但是在编码的时候,我的程序只对前4个数字排序。
代码
#include <stdio.h>
void sortArr(int *nums, int arrSize) {
// nums[start...end]
// nums[start...mid] n1
// nums[mid+1...end] n2
int start, mid, end;
start = 0;
end = arrSize-1;
mid = (end + start) / 2;
int n1, n2;
n1 = mid - start + 1;
n2 = end - mid;
int l[n1], r[n2];
for (int i = 0; i < n1; i++) {
l[i] = nums[start + i];
}
for (int i = 0; i < n2; i++) {
r[i] = nums[mid + 1 + i];
}
int i, j;
i = 0;
j = 0;
for (int k = start; k < arrSize; k++) {
if (l[i] <= r[j]) {
nums[k] = l[i];
i++;
} else {
nums[k] = r[j];
j++;
}
}
}
int main() {
int arr[] = {3, 41, 52, 26, 38, 57, 9, 49};
int arrsize = sizeof(arr) / sizeof(arr[0]);
printf("before sorting: \n");
for (int i = 0; i < arrsize; i++) {
printf("%d ", arr[i]);
}
sortArr(arr, arrsize);
printf("\n after sorting: \n");
for (int i = 0; i < arrsize; i++) {
printf("%d ", arr[i]);
}
return 0;
}
2条答案
按热度按时间xn1cxnb41#
你的代码有很多问题,包括你只实现了书中的MERGE(MERGESORT的一个子例程),书中使用了一个技巧,即在数组的“两半”后附加+infinity,以避免在合并时出现处理其中一半用完的代码。通过将
INT_MAX
追加到L和R并要求原始数组不包含该值),但您没有用任何内容替换它,因此您的代码在合并时很容易读取边界之外的内容。这是一个基于书本算法的工作版本。与问题中的代码相比,它还避免了VLA(可变长度数组),VLA在使用一次性
malloc
-ed缓冲区的大型输入数组上可能会失败,并使用更正确的size_t
作为数组索引。在合并时,代码在
if
语句中为li
和ri
添加了一些额外的测试,这与本书的+infinity技巧不同,在C中运行得更好。顶级函数MERGESORT如果成功返回1,如果不成功返回0(如果
malloc
失败,就会发生这种情况)。Assert用于检查关于各种索引和大小的假设--只有在代码中存在bug时才会失败,并且可以编译出来。它运行在一个可配置大小的随机数组上(当前为1234),并在末尾打印出
ok
或failed
,这取决于数组是否实际排序。(注意:rand
通常是要避免的,因为它通常是一个随机数的供应不足,但在这里它是好的)。请注意,这段代码是精心编写的,但它仍然没有得到很好的测试,所以你可能会发现错误!
k5ifujac2#
将此print命令添加到最后一个循环:
printf("%d %d %d\n", k, i, j);
n1 = n2 = 4
,所以两个数组的值都只到索引3为止。但在最后一个循环中,您从0到6运行i
。这是行不通的。您可以添加更多的打印命令,使用纸和笔运行算法,并希望找到出错的地方。