【问题标题】:Sort a two-dimensional array just like a one-dimensional array in C?像 C 中的一维数组一样对二维数组进行排序?
【发布时间】:2013-12-16 05:16:44
【问题描述】:

我想像这样对一个二维数组进行排序:

4 2 5
1 3 7
6 9 8

这样获得:

1 2 3
4 5 6
7 8 9

使用 C 语言。

解决此问题的几个选项可能包括:

  1. 将输入的二维数组转换为一维数组,并使用标准库函数,例如 sort。
  2. 正如有人建议here,我可以有一个定义或函数来使用一维索引访问每个值,并使用插入排序或冒泡排序。

    ARRAY(index) 数组[(index) / 3][(index) % 3]

我不喜欢任何一个选项,因为第一个需要临时空间,而第二个可能会很慢。我的二维数组的行和列都会很大。我也很懒,想知道我是否可以使用 qsort 的标准 C 库函数。似乎我不能将 qsort 与二维数组一起使用来获得所有元素的结果,就像一维数组一样。

我得到了一个二维数组,因此将其转换为一维数组对我来说不是一个选择。

感谢您的任何建议。

【问题讨论】:

  • 你如何声明你的二维数组?如果像 int a[2][3] 这样的东西,你可以把它当作一维数组。
  • 只是为了记录那些可能看不到下面讨论的人,我要使用的数组是动态分配的“int **a”。

标签: c sorting multidimensional-array quicksort bubble-sort


【解决方案1】:

正如公知涛在他的评论中提到的,如果数组定义为int `a[n][m]`,那么它在内存中被定义为一个连续的块,所以它可以像一个1一样被访问通过提供指向第一个元素的指针并提供 n*m 作为数组长度来创建一维数组。 您可以在问题 http://stackoverflow.com/questions/4810664/how-do-i-use-arrays-in-c/4810668 和 http://stackoverflow 中找到有关数组如何在 c 中工作的更详细的解释。 com/questions/7949​​589/2d-array-vs-array-of-arrays。

如果不是这样,那么使用访问函数是最好的选择,原因有两个:
1.这是最直观的做法。如果将数组定义为int* a[n],则可以有 n 个指向 m 个非连续数组的指针。这意味着就算法而言,您必须知道接下来会出现什么元素(用于排序),除非您为它定义了一个函数。
2.一点也不慢。您选择的任何排序算法的唯一变化是用您的新访问函数 (getArrayElement(a,i,j)) 替换每个一维数组访问 (a[i])。函数本身非常小,甚至可能在编译期间内联,因此唯一的开销是计算,每次访问需要两个额外的算术函数。由于不会改变算法的 O 复杂度(请参阅Wikipedia),这意味着它不会对减慢您的程序造成太大影响。

【讨论】:

  • 非常感谢您的回答。我认为我必须按照您的建议使用自定义排序功能。
  • 感谢您提供有关数组的两个链接。
【解决方案2】:
#include <stdio.h>
#include <stdlib.h>

int compare (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}

int main()
{
  int a[3][3] = {{4,2,5}, {1,3,7}, {6,9,8}};

  qsort(a, 9, sizeof(int), compare);

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

如果你声明你的数组像int **a。那么也许您可以使用以下技术,这需要一些额外的内存:

int *a_mem = (int *)malloc(9 * sizeof(int));
int **a = (int **)malloc(3 * sizeof(int *));
for (i = 0; i < 3; ++i)
  a[i] = &a_mem[i * 3];

qsort(a_mem, 9, sizeof(int), compare);

【讨论】:

  • 谢谢!这是一个如此简单明了的答案。
  • 只是一个注释:如果“a”数组被创建为“int **a”,那么qsort的第一个参数可以更改为*a。
  • @SangcheolChoi 嗨,如果您将数组声明为int **a,那么您可能不会使用它。因为这背后的假设是内存是连续的:)
  • @SangcheolChoi 或者,您可以为此使用一些额外的内存来化妆。我曾经使用过它。查看更新的 sn-p :)
  • 我是这么想的!因此,我编写的测试代码可能只是随机工作,因为内存恰好是连续分配的。那么,我应该使用上面 CurlyCorvus 建议的自定义排序功能吗?
猜你喜欢
  • 2017-05-25
  • 2012-04-03
  • 1970-01-01
  • 1970-01-01
  • 2018-06-02
  • 2017-04-18
  • 2018-07-26
  • 2013-08-17
  • 1970-01-01
相关资源
最近更新 更多