给定一个2d数组,每行从左到右排序,从最小到最大,我想将整个数组从最小到最大排序成一维数据。
行数为N,列数为M. 我需要的复杂性是M N log(N)
我想要做的是,在2d数组上进行某种合并排序,每次为函数发送2行,并且有点卡住了。
为该功能提供的签名是
void sort_rect(int a[N][M], int b[])
我承诺b的1d数组有足够的空间容纳2d数组的所有元素。#C !!!
答案 0 :(得分:1)
使用标准方法(合并已排序的数组然后排序)将为您提供O(NMLog(NM))
。如果您想要一种有效的方法,那么您应该使用min Heap数据结构。您可能想要了解堆数据结构
创建一个大小为N*M
的输出数组。这将保存输出排序数组。
创建一个大小为N
的最小堆。插入每个已排序数组的第一个元素。
从堆中删除顶部元素(最小值)并将其放入输出数组中。使用此删除元素所属的同一数组中的下一个元素放置此删除元素。重复此操作直到所有元素都被计算对
复杂性为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
}
算法如下:
element = queue.top()
)element.Value
添加到1d数组element.Row
queue.pop()
)对得到的1d数组进行排序,复杂度为O(MNlog(N))。这是因为您考虑了M * N个元素,并且对于每个元素,在priority_queue中添加/删除它需要log(N)时间,因为在任何给定时刻堆都不会超过N个元素。
我认为将2d数组视为1d并进行排序会导致MNlog(MN)复杂度有点差。