Created
October 25, 2012 22:24
-
-
Save reinh/3955850 to your computer and use it in GitHub Desktop.
Iterative Ruby Merge Sort
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module MergeSort | |
def self.sort(list) | |
list = list.map{|i| [i]} | |
list = pairs list while list.size > 1 | |
list.flatten | |
end | |
def self.pairs(list) | |
return list if list.size < 2 | |
x, y, *xs = list | |
[self.merge(x,y)] + self.pairs(xs) | |
end | |
def self.merge(xs, ys) | |
return ys if xs.empty? | |
return xs if ys.empty? | |
x, *xs_ = xs | |
y, *ys_ = ys | |
if x < y | |
[x] + merge(xs_, ys) | |
else | |
[y] + merge(ys_, xs) | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rspec' | |
require_relative 'merge_sort' | |
describe MergeSort, '.sort' do | |
it "sorts shit" do | |
examples = [ | |
[], | |
[1], | |
[2,1], | |
[6,2,3,1,7] | |
] | |
examples.each do |example| | |
MergeSort.sort(example).should == example.sort | |
end | |
end | |
end |
The iterative version is slower in Ruby than the recursive version right out of the gate. It's just interesting from a stylistic point of view.
For reference, here's the recursive version:
def self.recursive_sort(list)
size = list.size
return list if size < 2
mid = size/2
left, right = list[0,mid], list[mid, size]
merge recursive_sort(left), recursive_sort(right)
end
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Cool. Now switch to tail-recursive and turn on tail-call optimization. :)