如何对多维数组进行排序?

时间:2017-02-14 22:44:57

标签: c++ sorting multidimensional-array

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

#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,
  • 代码工作正常且易于管理任何数组,但维度数量。这是一种好方法还是另一种更好的选择?

1 个答案:

答案 0 :(得分: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的二维数组} 1}}并动态分配每行数据),然后将数组展平为临时一维数组,在一维数组上调用T**,并将一维数组复制回多维数组将是一个解决方案。