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

时间:2013-06-19 22:04:34

标签: c dynamic-arrays qsort

首先,我定义了一个包含2列和10行的动态数组。例如,整数number设置为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 );

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

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[1][0]) ) return -1;
    if ( (a[0][0] > b[0][0]) || (a[0][0] == b[0][0])&&(a[1][0] > b[1][0]) ) return +1;
    return 0;
}

问题

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

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

6 个答案:

答案 0 :(得分:13)

示例代码

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

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需要元素的每个元素地址(用于交换等。因为元素的大小和数量以及起始地址,因为只有给定的信息)。

E.g&amp;(int *),&amp;(int *)

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

在arg compare(int **, int **)

打电话&(int*) int**

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

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

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

答案 1 :(得分:0)

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

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]是第二个数组的第六个元素 - 与你应该做的比较完全无关。

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

将它们写为b[1][0]将提醒第一级间接是“单元素访问”指针。我不确定这是否会让整个事情变得更清楚。

答案 2 :(得分:0)

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

print(const initializer_list<int>& il)

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

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

答案 3 :(得分:0)

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

@BLUEPIXY,这是不正确的。 就够了

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

因为 pa 是 const void * (array[0]) 并且它很好地转换为 const int *

答案 4 :(得分:0)

const int (*a)[2] = *(const int (**)[2])pa;
const int (*b)[2] = *(const int (**)[2])pb;

@BLUEPIXY,这是不正确的。就够了

const int (*a)[2] = (int(*)[])pa;
const int (*b)[2] = (int(*)[])pb;

答案 5 :(得分:-1)

对于这个静态数组,

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);”在指针到指针实现的情况下。