备注:我考虑过基数排序、桶排序和计数排序。
有没有什么方法可以达到O(n)?
如果范围是固定且较小的(例如1..100),使用计数排序可以获得O(N)的时间复杂度。
这是Scala中的计数排序:
val res = Array.fill (100)(0)
val r = util.Random
// generate data to sort
val nums = for (i <- 1 to 1000*1000) yield r.nextInt (100)
for (i <- nums) res(i) += 1
println (res.mkString (" "))
对于任何感兴趣的人,我在阅读答案之前很快地编写了这个 Ruby 片段:
module Enumerable
def counting_sort(k)
reduce(Array.new(k+1, 0)) {|counting, n| counting.tap { counting[n] += 1 }}.
map.with_index {|count, n| [n] * count }.flatten
end
end
ary = Array.new(1_000_000){ rand(100) + 1 }
ary.counting_sort(100) # I'll spare you the output :-)
我甚至不知道它有一个名字。它应该能够传达这个想法,即使对于从未见过Ruby的人来说也是如此。(你唯一需要知道的是在Ruby中,K组合器被拼写为tap
)
而且它确实非常快,尽管不幸的是,我无法打败内置的手动优化的O(n log n)排序,在MRI、YARV和JRuby中都是用C编写的。
def sort(array)
sorted_array = Array.new(100,[])
array.each do |t|
sorted_array[t-1] = sorted_array[t-1] + [t]
end
sorted_array.flatten!
end