バケツソート
ハッシュと挿入ソートを組み合わせたソートである。
ハッシュ関数により、要素をいくつかの小さいバケツに分ける。
そして、それぞれのバケツの中で挿入ソートを行う。
挿入ソートはO(n^2)なので、それぞれのバケツ中の要素数が少ないほど高速。
したがって、O(n)の性能を出したいのであれば、
1つのバケツに入っている要素数が少なくなるよう、
適したハッシュ関数と十分に多数なバケツを用意する必要がある
今回はハッシュテーブルの長さ(バケツの個数)を4とした。
要素{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}に対応する。
なお、リンクつきリストでバケツを動的に確保する場合、固定長配列よりも高速になる。
#バケツソート #ハッシュと挿入ソートを組み合わせたソートである。 require "./shuttlesort.rb" @TableLength = 4 def myhash(key) return key / @TableLength end def bucketsort!(array) bucket = Array.new(@TableLength).map{ Array.new } #バケツに要素を加える array.each{|k| bucket[myhash(k)] << k } p bucket extract!(bucket, array) end #各バケツについて挿入ソートを行い、原配列に挿入 def extract!(bucket, array) indexInsert = 0 bucket.each{|b| shuttlesort!(b) if b.size > 0 b.each{|k| array[indexInsert] = k indexInsert += 1 } } end data = Array.new while input = $stdin.gets.to_i break if input < 0 data << input end p data bucketsort!(data) p data
もろもろで1時間30分ほど。
挿入ソートは、http://d.hatena.ne.jp/matasaburou/20131209/1386601142参照のこと。