如何排序比n log n更快(在列表中给出一个强大的条件)?

时间:2013-12-03 19:59:27

标签: c++ algorithm sorting

我被问到以下问题(根本不知道如何解决它的方法) 给定 n int的数组 arr ,我们需要对它进行排序。我们已经知道了这个{{1}的 k } s被放置在原始 arr 中,就像排序数组一样。(只是不知道它们中的哪一个) 他们说这种排序比int要好得多 - 我没有任何线索...... 有什么建议吗?

5 个答案:

答案 0 :(得分:4)

http://en.wikipedia.org/wiki/Radix_sort

关键的事实是你正在使用整数并且你知道最大的密钥,这正是使用基数排序时的复杂性和线性的复杂性。

也是第二种方法,如果它们中的k已经排序,你可以使用某种版本的shell排序,其序列将产生最佳结果

答案 1 :(得分:4)

当您的数组已经大部分排序时,选择排序是一个不错的选择;它应该只执行O(n(n-k)交换。如果排序的元素往往是连续的,那么Timsort也可能表现良好。当然,在任何情况下,对于足够小的k,你都不会比O(n log n)做得更好。

答案 2 :(得分:4)

如果我们不知道:

  1. kn如何相互关联
  2. 以及k元素在数组中的确切位置
  3. 在最坏的情况下,我们可以做得比Θ(nlog(n))好得多。

    为什么:

    1. k=1祝你好运......
    2. 让我们说k=0.9n并将k个元素放在前面。即使我们知道它们位于前面,我们仍然需要对大小0.1n进行排序,因此在最坏的情况下,我们需要0.1*n*log(0.1*n)=0.1*n*(log(0.1)+log(n))=0.01*nlog(n)-0.1*n比较Θ(n*log(n))
    3. 当然,这只是最坏情况的理论结果。实际上,在适当的位置上有正确k元素的信息可能会限制大量的工作。但是,我们确实需要了解kn(或者至少假设某些内容)。

答案 3 :(得分:0)

Adaptive sort是一种利用其输入中现有顺序的排序算法。插入排序是自适应排序之一,当阵列几乎排序时,它可以很好地工作。当然,最坏的情况是O(N ^ 2)。

还有其他自适应排序,例如 Adaptive heap sort,在构建堆时使用treap来利用有序元素。 Adaptive merge sort(Natural merge sort)Smoothsort

理论复杂度也将是O(N * lnN),但是当数据部分排序时,它们可能会更有效地执行。

答案 4 :(得分:-1)

算法:

  1. 按顺序找到k个连续元素的运行
  2. 对其他n-k元素进行排序
  3. 合并两个已排序的列表
  4. n = 8,k = 4的例子。

      

    ['echo','cat','bat','board','hand','hotel','kilo','hit']

    按顺序找到4个连续元素。

      

    ['echo','cat','bat','board','hand','hotel','kilo','hit']

    (碰巧,我们发现已经有5个了。好多了。)

    对其他元素进行排序

      

    [cat,echo,hit]

    合并两个排序列表

      

    ['bat','board','cat','echo','hand','hit','hotel','kilo']

    完成。

    这三个步骤的时间复杂性是

    1. O(n)的
    2. O((N-K)的log(n-k))的
    3. O(n)的
    4. 对于任何固定的比率k / n,第二步占主导地位(足够大的n)。