Reputation: 4796
I am trying to implement the quick sort algorithm using ruby. See what I did:
class Array
def quick_sort #line 14
less=[];greater=[]
if self.length<=1
self[0]
else
i=1
while i<self.length
if self[i]<=self[0]
less << self[i]
else
greater << self[i]
end
i=i+1
end
end
less.quick_sort + self[0] + greater.quick_sort #line 29
end
end
[1,3,2,5,4].quick_sort #line 32
This generated the error:
bubble_sort.rb:29:in `quick_sort': stack level too deep (SystemStackError)
from bubble_sort.rb:29:in `quick_sort'
from bubble_sort.rb:32
Why is this happening?
Upvotes: 2
Views: 6756
Reputation: 14453
I think the problem in your example was you needed an explicit return
.
if self.length<=1
self[0]
should have been
return [] if self == []
and
less.quick_sort + self[0] + greater.quick_sort #line 29
should have been
less.quick_sort + [self[0]] + greater.quick_sort #line 29
Here is a working example
class Array
def quick_sort
return [] if self == []
pivotal = self.shift;
less, greater = [], []
self.each do |x|
if x <= pivotal
less << x
else
greater << x
end
end
return less.quick_sort + [pivotal] + greater.quick_sort
end
end
[1,3,2,5,4].quick_sort # => [1, 2, 3, 4, 5]
Upvotes: 3
Reputation: 15712
In that part you should not handle the "=" case. Only < and > should be handled. Therefore your algorithm never stops and causes an infinite recursion.
if self[i]<=self[0]
less << self[i]
else
greater << self[i]
end
Upvotes: 1
Reputation: 370212
less.quick_sort + self[0] + greater.quick_sort
This line is outside of the if statement, so it gets executed whether self.length<=1
is true or not. Consequently the method recurses infinitely, which causes the stack to overflow.
It should also be pointed out that self[0]
does not return an array (unless self
is an array of arrays), so it does not make sense to use Array#+
on it. Nor does it make sense as a return value for your quick_sort method.
Upvotes: 1