快速实现:堆栈级别太深(SystemStackError)

时间:2011-11-08 22:10:40

标签: ruby algorithm

所以我试图在ruby中实现quicksort并且我得到这个错误`quicksort':堆栈级别太深(SystemStackError)

def quicksort(array)
  if array.length <= 1
    return array
  end
  less = Array.new
  greater = Array.new
  pivot = array[array.length/2]
  array.each do |x|
    if x < pivot
      less << x
    else 
      greater << x
    end
  end
  return quicksort(less) << pivot << quicksort(greater)
end

EDIT 我将else更改为elsif x > pivot,似乎有效。

4 个答案:

答案 0 :(得分:4)

当我生成一个用于测试的数组时,你的算法对我有用,甚至到1e7。

 quicksort Range.new(1,1e7).to_a.shuffle

当然,这需要大约4.5 GB的RAM才能完成。至于清理输出...

ruby-1.9.3-p0 :018 >       quicksort [1,3,2] # => [1, 2, [], 3, []] 
ruby-1.9.3-p0 :019 >     quicksort [1,4,2,3] # => [1, 2, [3, [4]]] 

更改此行:

  return (quicksort(less) << pivot << quicksort(greater)).flatten.compact

它使它变得更加清洁。

ruby-1.9.3-p0 :037 >       quicksort [1,3,2] # => [1, 2, 3] 
ruby-1.9.3-p0 :038 >     quicksort [1,4,2,3] # => [1, 2, 3, 4] 

答案 1 :(得分:1)

在ruby中,默认情况下堆栈大小设置得相当小。因此,使用大型数据集对堆栈进行递归函数并不太难。

确保无法无限递归的最简单方法是在非常小的数据集上运行quicksort。如果它仍然爆炸,你知道你无限复发。

您可以在Matz回复的this post中找到有关堆栈大小的一些信息。

答案 2 :(得分:1)

您需要删除数组中的数据透视表,因为您稍后会将其添加回来 所以而不是

pivot = array[array.length/2]

你应该做的

pivot = array.delete_at(array.length/2)

答案 3 :(得分:0)

您的函数无限递归。使用ruby-debug找出原因。

<强> EDIT1:

我认为你希望函数的最后一行是这样的:

return quicksort(less) + quicksort(greater)