# sort.rb
class Array
def insertion
(1..self.count).each do |i|
(i..0).each do |j|
first = j - 1
second = j
if self[second] > self[first]
swap(second, first)
end
end
end
self
end
def mergesort
return self if self.size <= 1
mid = self.size / 2
left = self[0, mid]
right = self[mid, self.size-mid]
merge_array(left.mergesort, right.mergesort)
end
# helpers
def merge_array(left, right)
sorted = []
until left.empty? or right.empty?
if left.first <= right.first
sorted << left.shift
else
sorted << right.shift
end
end
sorted.concat(left).concat(right)
end
def swap(previous, current)
copy = self[previous]
self[previous] = self[current]
self[current] = copy
end
end
私のrspecファイル:
require './sort'
unsorted = 5000.downto(1).to_a.shuffle
describe Array, "#insertion" do
it "sorts using insertion sort" do
time = Time.now
unsorted.insertion.should eq(unsorted.sort)
puts "insertion"
puts Time.now - time
end
end
describe Array, "#merge" do
it "sorts using merge sort" do
time = Time.now
unsorted.mergesort.should eq(unsorted.sort)
puts "merge"
puts Time.now - time
end
end
挿入ソートの実行時間は平均で O(n^2) であるのに対し、マージ ソートは O(n*log(n)) であるため、挿入ソートはマージ ソートよりも遅くなるはずです。しかし、上記のテスト コードを実行すると、マージは挿入よりも 10 倍以上遅くなります。
挿入 0.001294 秒 。マージ 0.017322 秒
私の推測では、shift
やconcat
のような計算コストの高い方法を使用していますが、10 倍の差があるのは大きすぎます。
マージソートを改善するにはどうすればよいですか?