给定范围 [0..n^3-1] 内的 n 个整数的输入集,提供线性时间排序算法。
这是我星期四测试的评论,我不知道如何解决这个问题。
给定范围 [0..n^3-1] 内的 n 个整数的输入集,提供线性时间排序算法。
这是我星期四测试的评论,我不知道如何解决这个问题。
看看基数排序。
当人们说“排序算法”时,他们通常指的是“比较排序算法”,这是任何仅取决于能够询问“这个东西比那个更大还是更小”的算法。因此,如果您仅限于询问有关数据的这一问题,那么您将永远不会得到超过 n*log(n) (这是对数据集的 n 阶乘可能排序进行 log(n) 搜索的结果) .
如果您可以摆脱“比较排序”的约束并针对一段数据提出更复杂的问题,例如“此数据的基数为 10 基数是什么”,那么您可以提出任意数量的线性时间排序算法,他们只是占用更多的内存。
这是一个时空权衡。比较排序需要很少或不需要 ram,并在 N*log(n) 时间内运行。基数排序(例如)在 O(n) 时间和 O(log(radix)) 内存中运行。
这真的很简单,如果 n=2 并且数字是唯一的:
复杂度 => O(2n)
否则,使用基数排序:
复杂度 => O(kn)(希望如此)
维基百科展示了许多不同的排序算法及其复杂性。你可能想检查一下
一组有限范围的数字可以由 RANGE 位的位图表示。在这种情况下,一个 500mb 的位图,所以对于除了巨大的列表之外的任何东西,你最好使用 Radix Sort。当你遇到数字 k 时,设置 bitmap[k] = 1。单次遍历列表,O(N)。
将数字视为三位数字,其中每个数字的范围从 0 到 n-1。使用基数排序对这些数字进行排序。对于每个数字,都会调用计数排序,它占用 Theta(n+n) 时间,因此总运行时间对应于 Theta(n)。
类似的算法是可能的:
M;// unsorted array
lngth; //number items of M
for(int i=0; i < lngth; i++)sorted[M[i]];
它是线性复杂度的唯一可能算法,但它的复杂度为 O(k*N) by ram(N - 数组元素,k - 元素的长度)