将具有排序行的2D数组合并为一个大的1D数组
Merging a 2D array with sorted rows into a big 1D array
给定一个2d数组,每一行从左到右,从最小到最大排序,我想把整个数组按从小到大排序成一个1D数组。
的行数为N,列数为M。需要的复杂度是MNlog(N)
我想做的是,在二维数组上做一些归并排序,每次发送2行给函数,这就是我卡住的地方。
函数的签名是
void sort_rect(int a[N][M], int b[])
我保证b的1d数组有足够的空间容纳2d数组的所有元素。#C!!
使用标准方法(合并排序数组然后排序)将得到O(NMLog(NM))
。如果你想要一个有效的方法,那么你应该使用最小堆数据结构。你可能想了解堆数据结构。
-
创建一个大小为
N*M
的输出数组,这将保存输出的排序数组 -
创建一个大小为
N
的最小堆,插入每个排序数组的第一个元素 -
从堆中移除顶部元素(最小)并将其放入输出数组中。将这个被删除的元素替换为该被删除元素所在的同一数组中的下一个元素。重复此操作,直到所有元素都被考虑在内。
复杂性将是O(NMLog(N))
。
由于a[M][N]
中的所有元素都位于顺序内存中,因此可以将该内存视为平面内存。你可以这样排序:
int *c = (int *)a;
和排序c
,给定数组的大小为M*N
。
或者你可以复制到b
,通过定义b
:
int b[sizeof(a) / sizeof(int)];
memcpy(b, a, sizeof(a));
和现在排序b
考虑一个归并排序,但是应用于N个数组而不是2个。对于每一行,都可以保留当前考虑的元素的索引。现在我们需要一些东西来比较所有N个值(而不仅仅是2个)。你可以做的是使用一个堆(priority_queue),它的元素结构像这样:
struct Element {
int Value;
int Row; //tells you which row in the 2d array the value comes from
}
算法如下:
- 将从第0列开始的所有值添加到优先级队列
- 声明一个数组,它将为每一行保留当前考虑的索引。初始化为0
- 在循环中(直到元素用完)
- 检查队列顶部的元素(
element = queue.top()
) - 添加
element.Value
到1d数组 - 当前考虑的
element.Row
索引增量 - 从优先队列的顶端移除元素(
queue.pop()
)
- 检查队列顶部的元素(
得到的1d数组被排序,复杂度为0 (MNlog(N))。这是因为您考虑了M*N个元素,并且对于每个元素添加/从priority_queue中删除它需要log(N)时间,因为在任何给定时刻堆保留的元素不超过N个。
我认为将2d数组视为1d并排序会导致MNlog(MN)复杂性,这有点糟糕。
- C++使用数组作为多维数组,尽管将其初始化为带有指针的 1D
- 为什么将指针重新分配给 1D 数组的 char 时显示错误,但 2D 数组工作正常?
- 如何使用指针C++将元素从2D数组复制到1D数组
- 借助功能将 2D 转换为 1D 数组
- 使用C++将1D数组转换为2D字符串数组
- C++ 矩阵乘法 2D 数组比 1D 更快
- 使用 std::transform 在 2d C 阵列上转换为 1d C 数组
- 在 C++ 中,用于将大型 2D 数组转换为 1D 数组的内存分配
- 将指向 1D Fortran 数组的指针传递给使用 C_LOC() 进行C++会导致垃圾值
- 表示为 1D 的多维数组(模板化为 n 维)
- 我的算法在 1D 数组中渲染矩形有什么问题
- 如何在C++中将 2d 矢量转换为 1d 数组?
- 在 C++ 中实现 1D 数组中的 2D 数组坐标
- 访问表示 2D 矩阵的 1D 存储数组
- C 将1D动态数组施放到2D数组以使用常规索引(例如ARR [i] [J])
- 如何将元素的索引从2D数组存储到1D数组中,然后交换这些值
- C++ 3D 数组到 1D 会导致堆缓冲区溢出
- 我在将 cv::Mat 保存到 1D 数组时遇到问题
- C ,将1D数组转换为2D数组
- 数组 1D 我需要要求用户检查索引和打印值