算法为第一个元素排序数组,然后是前2个元素,然后是前3个元素,依此类推

时间:2018-06-03 18:15:46

标签: c++ algorithm sorting

我有一个未排序的数字列表,我想要一个算法,这样我就可以得到第一个R元素的排序列表,但由于这个R对于不同的测试用例可能是不同的,我不想每次为第一个R排序数组元素。有没有办法让我完成这件事。一种可能的方法是保持向量数组,使得我有前1个数字排序,然后前2个数字排序,然后前3个数字排序等等,但它将需要1log1 + 2log2 + 3log3 + .... + nlogn时间,这是N ^ 2logN的复杂性。更快的方法可能吗?

3 个答案:

答案 0 :(得分:2)

在这种情况下,好的旧插入排序似乎比O(N ^ 2 lg N)更好,因为您不需要为每个{{从头开始排序元素1}}。 假设您在R中拥有n数组的已排序的第一个n元素的副本。 只需将1..R-1 - th元素插入R第一个元素(即O(R))的排序数组的副本中,即可获得R-1个第一个元素的排序数组。

如果你想要RN的每个R的结果,那就是O(1..N ^ 2),但实际上这个结果会小于O(N ^ 2),因为你可以按需生成排序数组,从最后排序的数组开始,元素少于R

答案 1 :(得分:2)

我们可以使用O(n log n)空格来保留合并排序的部分结果。然后,返回排序的第一个R元素的上限类似于合并log n排序列表。我找到了one reference,用于合并k n的{​​{1}}排序列表O(n * log k),这将使我们O(n * log log n),但希望很多查询都是均匀的效率更高。

13,15,12,4,18,1,23,17,6,2 ->

| 1   2   4   6   12   13   15   17   18   23 |
| 4   12   13   15   18 | 1   2   6   17  23  | 
| 13  15  | 4   12   18 | 1   23 | 2   6  17  |
| 13 | 15 | 12 | 4 | 18 | 1 | 23 | 17 | 6 | 2 |

答案 2 :(得分:1)

你可以试试quicksort,但不能完全做到。我听说Haskell以类似的方式做到了。

这几乎是通常的快速排序,但是你推迟了可以推迟的工作。

对于第一个元素,只需快速选择跳过与第一个元素无关的范围。但是对于每个下一个元素,您应该查找尚未分区的范围,但是需要它并对它们进行分区。

第一个元素的时间将为O(n)(并且您不太可能获得更好的效果),整个时间将为O(n * log n)

用于存储范围位置的额外内存似乎是O(log n),但我没有想到这一点足以确定。

更正:如果您需要每次输出整个子数组,只有在您一次输出数字时才会输出O(n^2),这将是O(n * log n)