如何使用归并排序对包含结构条目的数组进行排序?

huangapple go评论84阅读模式
英文:

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 &lt;= n1; i++) {
        tmp1[i] = record_arr[low + i];
    }
    for (j = 0; j &lt;= 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 &lt;= 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&#39; failed.
Aborted

答案1

得分: 2

你的实现依赖于一种易出错的技术,称为“哨兵”,其中在切片末尾插入一个已知大于所有有效值的值。这不是一个好主意,你应该改为比较索引值,仅比较切片内部的结构。

还要注意,只有左切片需要保存,右切片中的结构在比较之前从不被覆盖。

此外,你两次调用比较函数并测试明确的返回值 0-1。你应该只测试 &lt;= 0 以确定要复制哪个结构。

merge函数的末尾必须释放为副本分配的内存,否则内存将丢失。

这是修改后的版本:

void mergesort(struct record *record_arr, int low, int high) {
    if (low &lt; 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 &lt; n1; i++) {
        tmp1[i] = record_arr[low + i];
    }

    i = 0;
    j = mid + 1;
    k = low;
    while (i &lt; n1 &amp;&amp; j &lt;= high) {
        if (cmp_record(tmp1 + i, record_arr + j) &lt;= 0) {
            record_arr[k++] = tmp1[i++];
        } else {
            record_arr[k++] = record_arr[j++];
        }
    }
    while (i &lt; 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 &lt;= 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 &lt; 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 &lt; n1; i++) {
        tmp1[i] = record_arr[low + i];
    }

    i = 0;
    j = mid + 1;
    k = low;
    while (i &lt; n1 &amp;&amp; j &lt;= high) {
        if (cmp_record(tmp1 + i, record_arr + j) &lt;= 0) {
            record_arr[k++] = tmp1[i++];
        } else {
            record_arr[k++] = record_arr[j++];
        }
    }
    while (i &lt; n1) {
        record_arr[k++] = tmp1(i++];
    }
    free_memory(tmp1);
}

huangapple
  • 本文由 发表于 2023年4月11日 02:50:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/75979839.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定