根据第二行对二维数组进行排序
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;
}
我只是想解决这个问题,我可以使用其他功能。
L
和 R
数组的初始化循环不正确:您必须使用 {}
将多个语句分组为 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
传递给您的 mergeSort
和 merge
函数并明确定义 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, }];
我有一个数字数组,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;
}
我只是想解决这个问题,我可以使用其他功能。
L
和 R
数组的初始化循环不正确:您必须使用 {}
将多个语句分组为 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
传递给您的 mergeSort
和 merge
函数并明确定义 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, }];