C qsort()具有动态n乘2多维数组

首先,我定义了一个包含2列和10行的动态数组。 例如,这里整数设置为10。

 int** array; int number = 10; array = malloc(number * sizeof(int*)); for (i = 0; i < number; i++) array[i] = malloc(2 * sizeof(int)); 

然后我尝试使用qsort()

 qsort( array, number, sizeof array[0], compare ); 

这是我的比较function。 它按第一列中的整数值排序,然后按第二列排序,同时保留第一列中的顺序。 例如,“0 2,17,0 1”将变为“0 1,0 2,1 7”。

 int compare ( const void *pa, const void *pb ) { int (*a)[1] = pa; int (*b)[1] = pb; if ( (a[0][0] < b[0][0]) || (a[0][0] == b[0][0])&&(a[1][0]  b[0][0]) || (a[0][0] == b[0][0])&&(a[1][0] > b[1][0]) ) return +1; return 0; } 

这适用于静态数组。 我知道它现在不起作用,因为我有一个动态数组,这是一个指针数组。

如何调整此代码以使用动态创建的多维数组?

示例代码

 #include  #include  int compare ( const void *pa, const void *pb ) { const int *a = *(const int **)pa; const int *b = *(const int **)pb; if(a[0] == b[0]) return a[1] - b[1]; else return a[0] - b[0]; } /* #define NUMCMP(x,y) (((x) < (y)) ? -1 : ((x) > (y)) ? 1 : 0) int compare ( const void *pa, const void *pb ) { const int (*a)[2] = *(const int (**)[2])pa; const int (*b)[2] = *(const int (**)[2])pb; int tmp; if((tmp=NUMCMP((*a)[0], (*b)[0]))==0) return NUMCMP((*a)[1], (*b)[1]); else return tmp; } */ int main(void){ int **array; int number = 10; int i; array = malloc(number * sizeof(int*)); for (i = 0; i < number; i++){ array[i] = malloc(2 * sizeof(int)); array[i][0] = rand()%20; array[i][1] = rand()%20; } for(i = 0;i < number;++i) printf("%2d, %2d\n", array[i][0], array[i][1]); printf("\n"); qsort(array, number, sizeof array[0], compare); for(i = 0;i < number;++i) printf("%2d, %2d\n", array[i][0], array[i][1]); return 0; } 

什么 *(const int **)pa

array = {(int *),(int *),(int *),...,(int *)}

qsort需要元素的每个元素地址(用于交换等等。因为元素的大小和数量以及起始地址,因为只有给定的信息)。

例如&(int *),&(int *)

so (int **)传递给函数比较。

调用compare(int **, int **) &(int*)表示在arg int**

比较函数prototypeis cmp(const void*, const void*)

cast (const int**)pa被强制转换为传递原始指针。

*((const int **)pa)是取消引用原始元素指针( int*

由于现在有一个指针数组,比较函数的参数将成为指针的指针。 像这样使用它们:

 int *const *a = pa; int *const *b = pb; 

现在你有ab作为你正在排序的数组的两个指针。 每一个都指向sort函数要求您检查的单个元素。 您可以将这些元素作为*a*ba[0]b[0]但不应使用a[1]b[1] 。 如果sort函数要求你比较数组中的第一个元素( *a )和数组中的第五个元素( *b ),则a[1]b[1]是数组的第二个和第六个元素 – 完全与你应该做的比较无关。

在第一级解除引用后,您可以做任何您需要做的事情来检查被比较的元素。 由于您的数组元素本身是指向数组的指针(每个数组为2个int ),因此int可以作为a[0][0]进行访问a[0][1] b[0][0] b[0][1] 。 请注意,这与a[1][0]b[1][0]顺序相反。

将它们写为(*a)[0]将提醒第一级间接是“单元素访问”指针。 我不确定这是否会让整个事情更加清晰。

我遇到了这个线程,寻找我的同一个问题,最后我最后做了下面的事情。

 static int compareMatrixElements(const void *p1, const void *p2) { return ((*(int const *) p1) - (*(int const *) p2)); } void sortMatrix(int** matrix, int r, int c) { int sort_matrix[r][c]; for(int i = 0; i < r; i++) { memcpy(sort_matrix[i], matrix[i], c * sizeof(int)); } qsort(sort_matrix, r*c, sizeof(int), compareMatrixElements); for(int i = 0; i < r; i++) { memcpy(matrix[i], sort_matrix[i], c * sizeof(int)); } } 

在我的上面的代码中我直接使用了qsort API,可以在连续的内存中使用这个api或任何其他排序算法,但是如果你有一个矩阵,其行是指向其列的内存的指针(就像我的情况一样)以及在这个线程的问题中描述)。 因此,我将这样的矩阵复制到一个连续的内存中,对该连续的内存进行排序,并将已排序的元素复制回矩阵。

上面的解决方案对我有用,我认为它可能对其他人有帮助,所以我发布了它,建议任何改进。

对于此静态数组,sizeof array [0]将为“2 * sizeof(int)”。

 int array[10][2]; 

对于这个指向指针的指针,sizeof array [0]将是“sizeof(int *)”。 对于这个指向指针的指针,sizeof array [0] [0]将是“sizeof(int)”。

 int **array; 

所以,首先你不能使用“qsort(array,number,sizeof array [0],compare);” 在指针到指针实现的情况下。