在C中有效地对二维数组的列进行排序

时间:2015-12-01 09:41:17

标签: c arrays sorting multidimensional-array quicksort

我通过malloc在C中创建一个二维数组,如下所示:

double **x;     
x = malloc(rows * sizeof(double*));
for (n = 0; n < rows; n++){
    x[n] = malloc(columns * sizeof(double));
    memset(x[n], 0, columns * sizeof(double));
}

我还检查malloc是否失败,但为了更好的可读性,我发布了该版本。它实际上工作正常。

现在我有一个函数,它按顺序排列元素:

double qsort_row_wise(double points[], int points_count)

我可以通过以下方式调用特定行(第3/4行)和4 + 1列:

my_qsort(x[3], 4);

此函数正在接收正常数组,并且运行良好。

现在我想使用此函数来排序列。这就是为什么我要搜索这样的东西(这不起作用):

my_qsort(x[][3], 4);

x [] [3]这里指的是第3列的所有元素的向量。

如果可能的话,我想做一个&#34;矢量&#34;类操作,而不是一步一步地选择所有内容(for loop)以获得最佳性能。

3 个答案:

答案 0 :(得分:4)

由于您需要2D数组,因此最好将其分配为单个连续块:

double *x = calloc(rows * columns, sizeof(double)); // does zero init

现在您可以使用算术进行索引,因此您的my_qsort函数应该声明为:

void my_qsort(double *start, size_t count, size_t stride);

现在要排序第3行,你可以这样做:

my_qsort(x + 3 * columns, columns, 1);

要对第5列进行排序,您可以这样做:

my_qsort(x + 5, rows, columns);

在排序过程中,您需要访问的元素为start[ii * stride],其中ii0转到count。当然,start只是您希望排序的2D数组中的第一个单元格 - 通常是行中最左边的单元格或列中的顶部单元格。也可以使用相同的函数对行或列的一部分进行排序,或者通过矩阵对任意“行”进行排序,例如,方阵的对角线:

my_qsort(x, rows, columns + 1);

只需一次分配来存储您的2D数组,不仅可以简化“跨步”操作,而且效率更高,因为它减少了分配次数,改善了空间局部性,并且在Linux上增加了内存的可能性在您free时立即回收,因为“大”分配是通过mmap而不是sbrk完成的。

答案 1 :(得分:2)

好吧,你需要创建一个数组,其数量大小是你有多少行,因为一列由n行组成。

double *cols = malloc(nofrows * sizeof(double));

然后遍历行上的二维数组并使用列索引作为常量:

int whichcolumn = 1;
for (int i = 0; i < rows; i++)
  cols[i] = x[i][whichcolumn];

然后将cols传递给qsort函数

qsort_row_wise(cols, nofrows);

答案 2 :(得分:1)

  

如果可能的话,我想进行矢量操作,而不是逐步选择所有内容(for loop)以获得最佳性能。

这是不可能的。

你的第一个代码片段创建的不是2D数组,而是一个指针的一维数组,每个元素指向double的1D数组。这种结构有时被称为“分散”数组,因为它由“行数”+1组成,不一定是连续的内存块。

从后一个事实得出结论,您无法提取列,因为元素分布在整个内存中,并且无法通过单个操作进行寻址。