正如标题所暗示的那样,我想知道合并k个排序大小为n的数组下限的证明是什么?我知道界限是O(kn * log [k]),但这是如何实现的?我尝试比较使用决策树对p元素数组进行排序,但我不知道如何实现此证明。
答案 0 :(得分:1)
这很容易证明,尝试以合并排序的方式考虑它。
合并排序大小 K * N 的数组取 O(KN * log(K * N))。
但我们不必达到大小 1 的 leafs ,因为我们知道当数组大小为 N 时它会被排序。为简单起见,我们假设 K 是2的幂。
我们需要多少次除以2才能达到大小为N的叶子?
K 次!
<强>可视化强>
因此,您有 log(k)步骤,然后必须合并每个步骤 K N ,并且有 log(k)步骤。因此,时间复杂度 O(NK (log(K))
证明:
让我们假设它不是下限,我们可以做得更好。然后,对于任何大小 N * K 的未知数组,我们可以将其拆分为2,直到我们到达大小为 N 的子数组,对每个大小为N的数组进行合并排序在 Nlog(N)时间内以及所有阵列的总数 K * N * log(N)时间。
在对大小为N的K阵列进行排序后,我们必须将它们合并为更大的 N * K 阵列,支付小于 O(NK *(log(K) ),因为我们假设它不是下限。
最后,您排序了一个大小为N * K的未知数组,其复杂度小于 N * K * log(N * K),这在比较模型中是不可能的。
因此,在合并大小为N的K排序数组时,你不能比 O(NK *(log(K))更好。
答案 1 :(得分:1)
可能的实施。
让我们创建一个heap data structure来存储按元素排序的(element, arrayIndex)
对。然后
p
,将p.element
添加到结果中,然后将具有下一个元素的对(next, p.arrayIndex)
插入堆中具有p.arrayIndex
索引的数组(如果它不为空)。 对于跟踪'next'元素,您需要一个带有k
索引/指针/迭代器的数组,这些数组指向相应数组的下一个元素。
堆中最多会有k
个元素,因此堆的insert
/ remove
操作将具有O(log(k))
复杂度。每个元素都将从堆中插入和删除一次。元素数量为n*k
。总体复杂度为O(n*k*log(k))
。
答案 2 :(得分:0)
创建一个大小为k的最小堆,它存储来自每个k数组的下一个项目。每个节点还存储它来自哪个阵列。通过将堆中的min添加到final_sorted_array,然后将值中的下一个元素添加到堆中来创建排序数组。
删除堆的最小值是O(log k)。你有NK元素,所以你做NK次。最终结果:O(NK log k)。