将具有已排序行的2D数组合并为大型1D数组

时间:2016-08-22 08:53:20

标签: c++ c arrays algorithm sorting

给定一个2d数组,每行从左到右排序,从最小到最大,我想将整个数组从最小到最大排序成一维数据。

行数为N,列数为M. 我需要的复杂性是M N log(N)

我想要做的是,在2d数组上进行某种合并排序,每次为函数发送2行,并且有点卡住了。

为该功能提供的签名是

void sort_rect(int a[N][M], int b[])

我承诺b的1d数组有足够的空间容纳2d数组的所有元素。#C !!!

3 个答案:

答案 0 :(得分:1)

使用标准方法(合并已排序的数组然后排序)将为您提供O(NMLog(NM))。如果您想要一种有效的方法,那么您应该使用min Heap数据结构。您可能想要了解堆数据结构

  1. 创建一个大小为N*M的输出数组。这将保存输出排序数组。

  2. 创建一个大小为N的最小堆。插入每个已排序数组的第一个元素。

  3. 从堆中删除顶部元素(最小值)并将其放入输出数组中。使用此删除元素所属的同一数组中的下一个元素放置此删除元素。重复此操作直到所有元素都被计算对

  4. 复杂性为O(NMLog(N))

答案 1 :(得分:0)

由于a[M][N]中的所有元素都位于顺序内存中,因此您可以将该内存视为平坦内存。所以你按照这样排序:

int *c = (int *)a;

并对c进行排序,因为数组的大小为M*N

或者您可以通过这样定义b将其复制到b

int b[sizeof(a) / sizeof(int)];
memcpy(b, a, sizeof(a));

现在排序b

答案 2 :(得分:0)

考虑合并排序,但应用于N个数组而不是2.对于每一行,您可以保留当前被考虑的元素的索引。现在我们需要一些东西来比较所有的N值(而不仅仅是2)。你可以做的是使用一个堆(priority_queue),其元素结构如下:

struct Element {
   int Value;
   int Row; //tells you which row in the 2d array the value comes from
}

算法如下:

  1. 您将第0列中的所有值添加到优先级 队列
  2. 声明一个数组,它将保留当前每行的索引。将其初始化为零。
  3. 在一个循环中(直到你用完了元素)
    • 检查队列顶部的元素(element = queue.top()
    • element.Value添加到1d数组
    • 增量目前被视为element.Row
    • 的索引
    • 从优先级队列(queue.pop()
    • 的顶部删除元素
  4. 对得到的1d数组进行排序,复杂度为O(MNlog(N))。这是因为您考虑了M * N个元素,并且对于每个元素,在priority_queue中添加/删除它需要log(N)时间,因为在任何给定时刻堆都不会超过N个元素。

    我认为将2d数组视为1d并进行排序会导致MNlog(MN)复杂度有点差。