ruby的递归调用中的堆栈级别太深错误

时间:2011-04-17 14:13:20

标签: ruby

我正在尝试使用ruby实现快速排序算法。看看我做了什么:

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

这产生了错误:

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

为什么会这样?

3 个答案:

答案 0 :(得分:3)

我认为您的示例中的问题是您需要一个明确的return

if self.length<=1
  self[0]

应该是

return [] if self == []

less.quick_sort + self[0] + greater.quick_sort #line 29

应该是

less.quick_sort + [self[0]] + greater.quick_sort #line 29

这是一个工作示例

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]

答案 1 :(得分:1)

less.quick_sort + self[0] + greater.quick_sort

这一行在if语句之外,因此无论self.length<=1是否为真,它都会被执行。因此,该方法无限递归,导致堆栈溢出。

还应该指出self[0]不返回数组(除非self是一个数组数组),因此在它上面使用Array#+是没有意义的。作为quick_sort方法的返回值,它也没有意义。

答案 2 :(得分:1)

在那部分你不应该处理“=”的情况。只有&lt;和&gt;应该处理。因此,您的算法永远不会停止并导致无限递归。

if self[i]<=self[0]
  less << self[i]
else
  greater << self[i]
end