这是我的代码。
@@inversions = 0
numbers = [very big array]
def merge_sort(array)
return array if array.size <= 1
left = array.slice(0, (array.size / 2).round)
right = array - left
merge(merge_sort(left), merge_sort(right))
end
def merge(left, right)
return right if left.empty? # crashes here with stack level too deep
return left if right.empty?
if left.first <= right.first
[left.first] + merge(left[1..-1], right)
else
@@inversions += left.size
[right.first] + merge(left, right[1..-1])
end
end
你能说出它失败的原因吗? (适用于小于~15000大小的数组)
答案 0 :(得分:3)
您的递归合并功能可能就是原因。对于数组中的每个元素,您在堆栈中更深一层。标准合并排序不应该比lg(N)更深。尝试重写merge
是迭代的而不是递归的。
像
这样的东西def merge left,right
a = []
while !left.empty? and !right.empty?
if left.first < right.first
a<<left.shift
else
a<<right.shift
end
end
a + left + right
end
答案 1 :(得分:0)
你跑出了堆栈室 - 显然 - 但我认为你需要知道这意味着什么所以这里有一些理论。我的基础是古老的'汇编',但这是一般问题。
在计算机体系结构中,芯片的一个区域专用于“堆栈”,通常是LIFO(后进先出)'暂存器'。数据被“推送”并“弹出”进入和离开堆栈有时会自动进行,有时也会被程序员选择。
这个堆栈有一个有限的长度(在溢出这个堆栈的* 86中覆盖了芯片的其他特殊区域(EIP),这是改变程序流控制的经典黑客技术,但无论如何......
在你的程序中,每次递归或方法调用发生时,堆栈都会加载调用代码的返回地址(因此它可以返回并继续)。这就是导致堆栈溢出的原因。