【问题标题】:How to sort a multi-dimension array?如何对多维数组进行排序?
【发布时间】:2017-07-03 10:04:30
【问题描述】:

您好,我编写了一个程序来使用冒泡排序对多维数组进行排序。我发现随着维度的增加对多维数组进行排序有点困难,所以我使用了一种技术:将多维数组复制到线性数组,然后对后者进行排序,然后将其复制回原始数组:

#include <iostream>

int main(){

    const int d1 = 2, d2 = 3, d3 = 2;
    int array[d1][d2][d3] = {
        { {5 ,  7}, {2, 55}, {17, 23} }, 
        { {57, 77}, {1, 0} , {21, 16} }
        };

    std::cout << "Before sorting: " << std::endl << std::endl;

    for(int i(0); i < 2; i++){
        for(int j(0); j < 3; j++){
            for(int k(0); k < 2; k++)
                std::cout << array[i][j][k] << ", ";
            std::cout << " ";
        }
        std::cout << std::endl;
    }

    std::cout << std::endl;

    const int size = d1 * d2 * d3;
    int array2[size] = {0};

    memcpy(array2, array, sizeof(int) * size);

    for(int i(0); i < size; i++)
        std::cout << array2[i] << ", ";
    std::cout << std::endl << std::endl;

    for(int i(0); i < size; i++)
        for(int j(i + 1); j < size; j++)
            if(array2[i] > array2[j]){
                array2[i] ^= array2[j];
                array2[j] ^= array2[i];
                array2[i] ^= array2[j];
            }

    for(int i(0); i < size; i++)
        std::cout << array2[i] << ", ";
    std::cout << std::endl << std::endl;

    memcpy(array, array2, sizeof(int) * size);

    std::cout << "After sorting:" << std::endl << std::endl;
    for(int i(0); i < 2; i++){
        for(int j(0); j < 3; j++){
            for(int k(0); k < 2; k++)
                std::cout << array[i][j][k] << ", ";
            std::cout << " ";
        }
        std::cout << std::endl;
    }

    std::cout << std::endl;
    return 0;
}

输出:

Before sorting:

5, 7,  2, 55,  17, 23,
57, 77,  1, 0,  21, 16,

5, 7, 2, 55, 17, 23, 57, 77, 1, 0, 21, 16,

0, 1, 2, 5, 7, 16, 17, 21, 23, 55, 57, 77,

After sorting:

0, 1,  2, 5,  7, 16,
17, 21,  23, 55,  57, 77,
  • 代码工作正常,易于管理任何数组,无论维数如何。这是一个好方法还是有其他更好的选择?

【问题讨论】:

  • const int size = d1 * d2 * d3;
  • @LWimsey:我编辑了代码。 int那里是必须的吗?
  • 是的,因为你不能声明一个没有类型的变量
  • 您可以对数组进行就地排序,就像我的示例一样。数组将其数据存储在连续内存中,因此您只需要知道第一个元素的地址和最后一个元素的地址。一旦你有了这两个项目,那么任何传统的排序算法都可以工作,因为它只是一个线性序列。
  • @Lee_Wong Here is another example。我不想将这些示例作为答案发布,因为我不知道您是在寻找通用的多维数组排序,还是在寻找对多维数组进行排序的更简单的代码。

标签: c++ sorting multidimensional-array


【解决方案1】:

C++ 中的多维数组将其数据存储在连续内存中。因此,使用 STL std::sort 算法函数对数组进行排序所需的全部内容是获取指向第一项和最后一项的指针。

这将比尝试编写自己的排序更容易,并且很可能运行得更快,因为不需要将数组“展平”为临时的一维数组,并且您正在利用std::sort 保证对数运行时复杂度(与具有O(n^2) 复杂度的冒泡排序相反)。

这是使用std::sort 对问题中的数组进行排序的示例:

#include <iostream>
#include <algorithm>

int main()
{
    const int d1 = 2, d2 = 3, d3 = 2;
    int array[d1][d2][d3] = {
        { {5 ,  7}, {2, 55}, {17, 23} }, 
        { {57, 77}, {1, 0} , {21, 16} }
        };

    // get the number of elements
    const int numberOfElements = sizeof(array) / sizeof(int);

    // get pointers to first and one past the last element
    int *first = &array[0][0][0];
    int *last = first + numberOfElements;

    // call sort function
    std::sort(first, last);

    // output results. 
    for(int i = 0; i < d1; ++i)
      for (int j = 0; j < d2; ++j)
         for (int k = 0; k < d3; ++k)
             std::cout << array[i][j][k] << "\n";
}                  

Live Example

如果您必须编写冒泡排序(或任何其他类型的排序),基本推理仍然适用。只要得到指向第一项的指针,就可以写出传统的冒泡排序,as shown here

补充说明:

由于多维数组将项目存储在连续内存中,因此不仅std::sort 可以工作,任何STL 算法都可以在序列上工作(例如,std::uniquestd::partition 等)

未布置在连续内存中的数组

如果您创建了一个在连续内存中布局数据的“数组”(例如,使用T** 动态创建一个T 类型的二维数组和动态分配每一行数据),然后将数组展平为临时一维数组,在一维数组上调用std::sort,并将一维数组复制回多维数组将是一种解决方案。

【讨论】:

  • 最后一个问题:在您提供的链接中:if (*(first+j) &gt; *(first+j+1)) std::swap(*(first+j), *(first+j+1)); 是否等同于:if (first[j] &gt; first[j+1]) std::swap(first[j], first[j+1]);
  • 是的。您可以使用数组语法。
  • 好的,感谢您提供了良好而彻底的解释。这真的很有帮助。
猜你喜欢
  • 2021-07-02
  • 2017-08-27
  • 1970-01-01
  • 2010-10-13
  • 1970-01-01
  • 2014-05-13
  • 2021-07-11
相关资源
最近更新 更多