根据第二行对二维数组进行排序

Sorting a 2d array based on second row

我有一个数字数组,a[n],我想快速排序,但我想保存原来的位置。所以我认为我应该使用二维数组 a[2][n],因此 a[0][n] 用于初始位置,a[1][n] 用于值。所以我想根据第二行对这个数组进行排序。 例如,我的数组是

a[2][5] = [{ 0, 1, 2, 3, 4 }, { 10, 30, 40, 20, 50 }];

排序后我想要

a[2][5] = [{ 0, 3, 1, 2, 4 }, { 10, 20, 30, 40, 50 }];

我尝试更改合并排序,以便它根据第二行对第一行进行排序(并且还对第二行进行排序)但是第 14 行存在分段错误,这是我的代码

#include <stdio.h>
#include <stdlib.h>

void merge(int arr[][201], int l, int m, int r) {
    int i, j, k;
    int n1 = m - l + 1;
    int n2 = r - m;

    /* create temp arrays */
    int L[2][n1], R[2][n2];

    /* Copy data to temp arrays L[] and R[] */
    for (i = 0; i < n1; i++)
        L[1][i] = arr[1][l + i];
        L[0][i] = arr[0][l + i];
    for (j = 0; j < n2; j++)
        R[1][j] = arr[1][m + 1 + j];
        R[0][j] = arr[0][m + 1 + j];

    /* Merge the temp arrays back into arr[l..r]*/
    i = 0; // Initial index of first subarray
    j = 0; // Initial index of second subarray
    k = l; // Initial index of merged subarray
    while (i < n1 && j < n2) {
        if (L[1][i] <= R[1][j]) {
            arr[1][k] = L[1][i];
            arr[0][k] = L[0][i];
            i++;
        } else {
            arr[1][k] = R[1][j];
            arr[0][k] = R[0][j];
            j++;
        }
        k++;
    }

    /* Copy the remaining elements of L[], if there
    are any */
    while (i < n1) {
        arr[0][k] = L[0][i];
        arr[1][k] = L[1][i];
        i++;
        k++;
    }

    /* Copy the remaining elements of R[], if there
    are any */
    while (j < n2) {
        arr[1][k] = R[1][j];
        arr[0][k] = R[0][j];
        j++;
        k++;
    }
}

/* l is for left index and r is right index of the
sub-array of arr to be sorted */
void mergeSort(int arr[][201], int l, int r) {
    if (l < r) {
        // Same as (l+r)/2, but avoids overflow for
        // large l and h
        int m = l + (r - l) / 2;

        // Sort first and second halves
        mergeSort(arr, l, m);
        mergeSort(arr, m + 1, r);

        merge(arr, l, m, r);
    }
}

void get_array(int length, int array[]) {
    for (int i = 0; i < length; i++) {
        scanf("%d", &array[i]);
    }
}

int main() {
    int  n;
    scanf("%d", &n);

    int packages[2][n];
    
    for (int i = 0; i < n; i++) {
        packages[0][i]= i;
    }
    get_array(n, packages[1]);
    mergeSort(packages, 0, n);

    return 0;
}

我只是想解决这个问题,我可以使用其他功能。

LR 数组的初始化循环不正确:您必须使用 {} 将多个语句分组为 C 中的一个块。与 Python 不同,缩进不决定结构:

for (i = 0; i < n1; i++) {
    L[1][i] = arr[1][l + i];
    L[0][i] = arr[0][l + i];
}
for (j = 0; j < n2; j++) {
    R[1][j] = arr[1][m + 1 + j];
    R[0][j] = arr[0][m + 1 + j];
}

此外,您的排序函数需要一个具有固定列数 201 的二维数组,因此您不能将在 main() 中分配的具有可变列数的数组传递给它。您必须使用固定数组 int packages[2][201]; 或将 n 传递给您的 mergeSortmerge 函数并明确定义 arr

您应该将 n - 1 作为初始调用中最后一个元素的偏移量传递给 mergeSort()。此约定容易出错且令人困惑。

另请注意,merge可以简化:只需要保存左边的部分,并且需要一个循环。

这是修改后的版本:

#include <stdio.h>
#include <stdlib.h>

void merge(int n, int arr[][n], int l, int m, int r) {
    int i, j, k;
    int n1 = m - l;

    /* create temp array */
    int L[2][n1];

    /* Copy data to temp array L[] */
    for (i = 0; i < n1; i++) {
        L[1][i] = arr[1][l + i];
        L[0][i] = arr[0][l + i];
    }

    /* Merge the temp arrays back into arr[l..r]*/
    i = 0; // Initial index of first subarray
    j = m; // Initial index of second subarray
    k = l; // Initial index of merged subarray
    while (i < n1) {
        if (j == r || L[1][i] <= arr[1][j]) {
            arr[1][k] = L[1][i];
            arr[0][k] = L[0][i];
            i++;
        } else {
            arr[1][k] = arr[1][j];
            arr[0][k] = arr[0][j];
            j++;
        }
        k++;
    }
}

/* l is for left index and r is right index of the
   sub-array of arr to be sorted */
void mergeSort(int n, int arr[][n], int l, int r) {
    if (r - l > 1) {
        // Same as (l+r)/2, but avoids overflow for
        // large l and h
        int m = l + (r - l) / 2;

        // Sort first and second halves
        mergeSort(n, arr, l, m);
        mergeSort(n, arr, m, r);
        merge(n, arr, l, m, r);
    }
}

int main() {
    int n = 0;
    scanf("%d", &n);

    int packages[2][n];

    for (int i = 0; i < n; i++) {
        packages[0][i] = i;
        packages[1][i] = 0;
        scanf("%d", &packages[1][i]);
    }
    mergeSort(n, packages, 0, n);

    printf("a[2][%d] = [{ ", n);
    for (int i = 0; i < n; i++) {
        printf("%d, ", packages[0][i]);
    }
    printf("}, { ");
    for (int i = 0; i < n; i++) {
        printf("%d, ", packages[1][i]);
    }
    printf("}];\n");
    return 0;
}

输出:

5 10 30 40 20 50
a[2][5] = [{ 0, 3, 1, 2, 4, }, { 10, 20, 30, 40, 50, }];