英文:
How to use sort an array with struct entries using mergesort?
问题
以下是您的代码的翻译部分:
这是我为`merge`函数编写的代码
void merge(struct record *record_arr, int low, int mid, int high) {
int i, j, k;
int n1 = mid - low + 1;
int n2 = high - mid;
struct record *tmp1 = (struct record *)allocate_memory((n1 + 1) * sizeof(struct record));
struct record *tmp2 = (struct record *)allocate_memory((n2 + 1) * sizeof(struct record));
for (i = 0; i <= n1; i++) {
tmp1[i] = record_arr[low + i];
}
for (j = 0; j <= n2; j++) {
tmp2[j] = record_arr[mid + 1 + j];
}
tmp1[i + 1] = (struct record){ 0 };
tmp2[j + 1] = (struct record){ 0 };
i = j = 0;
for (k = low; k <= high; k++) {
if ((cmp_record(tmp1 + i, tmp2 + j) == 0) || (cmp_record(tmp1 + i, tmp2 + j) == -1)) {
record_arr[k] = tmp1[i];
i++;
} else {
record_arr[k] = tmp2[j];
j++;
}
}
}
实施后,数组未被排序,出现以下错误:
运行包含10个输入的TEST2
数组未排序
test2:lib.c:527:check_array_is_sorted_by_uid:断言`0'失败。
中止
英文:
This is the code that I have written for the merge
function
void merge(struct record *record_arr, int low, int mid, int high) {
int i, j, k;
int n1 = mid - low + 1;
int n2 = high - mid;
struct record *tmp1 = (struct record *)allocate_memory((n1 + 1) * sizeof(struct record));
struct record *tmp2 = (struct record *)allocate_memory((n2 + 1) * sizeof(struct record));
for (i = 0; i <= n1; i++) {
tmp1[i] = record_arr[low + i];
}
for (j = 0; j <= n2; j++) {
tmp2[j] = record_arr[mid + 1 + j];
}
tmp1[i + 1] = (struct record){ 0 };
tmp2[j + 1] = (struct record){ 0 };
i = j = 0;
for (k = low; k <= high; k++) {
if ((cmp_record(tmp1 + i, tmp2 + j) == 0) || (cmp_record(tmp1 + i, tmp2 + j) == -1)) {
record_arr[k] = tmp1[i];
i++;
} else {
record_arr[k] = tmp2[j];
j++;
}
}
}
After implementing it, the array is not being sorted and I am getting this error
Running TEST2 for 10 inputs
array is not sorted
test2: lib.c:527: check_array_is_sorted_by_uid: Assertion `0' failed.
Aborted
答案1
得分: 2
你的实现依赖于一种易出错的技术,称为“哨兵”,其中在切片末尾插入一个已知大于所有有效值的值。这不是一个好主意,你应该改为比较索引值,仅比较切片内部的结构。
还要注意,只有左切片需要保存,右切片中的结构在比较之前从不被覆盖。
此外,你两次调用比较函数并测试明确的返回值 0
和 -1
。你应该只测试 <= 0
以确定要复制哪个结构。
在merge
函数的末尾必须释放为副本分配的内存,否则内存将丢失。
这是修改后的版本:
void mergesort(struct record *record_arr, int low, int high) {
if (low < high) {
int mid = low + (high - low) / 2;
mergesort(record_arr, low, mid);
mergesort(record_arr, mid + 1, high);
merge(record_arr, low, mid, high);
}
}
void merge(struct record *record_arr, int low, int mid, int high) {
int i, j, k;
int n1 = mid - low + 1;
int n2 = high - mid;
// 保存左切片中的结构
struct record *tmp1 = (struct record *)allocate_memory(n1 * sizeof(struct record));
for (i = 0; i < n1; i++) {
tmp1[i] = record_arr[low + i];
}
i = 0;
j = mid + 1;
k = low;
while (i < n1 && j <= high) {
if (cmp_record(tmp1 + i, record_arr + j) <= 0) {
record_arr[k++] = tmp1[i++];
} else {
record_arr[k++] = record_arr[j++];
}
}
while (i < n1) {
record_arr[k++] = tmp1[i++];
}
free_memory(tmp1);
}
英文:
Your implementation relies on an error prone technique called sentinels where a value known to be larger than all valid values is inserted at the end of the slices. This is not a good idea, you should instead compare the index values and only compare the structures inside the slices.
Note also that only the left slice needs saving, structures in the right slice are never overwritten before they are compared.
Furthermore, you call the comparison function twice and test for explicit return values 0
and -1
. You should just test for <= 0
to determine which structure to copy.
Memory allocated for the copies must be freed at the end of the merge
function, otherwise the memory is lost.
Here is a modified version:
void mergesort(struct record *record_arr, int low, int high) {
if (low < high) {
int mid = low + (high - low) / 2;
mergesort(record_arr, low, mid);
mergesort(record_arr, mid + 1, high);
merge(record_arr, low, mid, high);
}
}
void merge(struct record *record_arr, int low, int mid, int high) {
int i, j, k;
int n1 = mid - low + 1;
int n2 = high - mid;
// save structures from the left slice
struct record *tmp1 = (struct record *)allocate_memory(n1 * sizeof(struct record));
for (i = 0; i < n1; i++) {
tmp1[i] = record_arr[low + i];
}
i = 0;
j = mid + 1;
k = low;
while (i < n1 && j <= high) {
if (cmp_record(tmp1 + i, record_arr + j) <= 0) {
record_arr[k++] = tmp1[i++];
} else {
record_arr[k++] = record_arr[j++];
}
}
while (i < n1) {
record_arr[k++] = tmp1(i++];
}
free_memory(tmp1);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论