在最小尺寸N = ~1950左右的较小列表上,我得到正确的输出......但是,不大得多的列表大小会返回错误而不是预期结果。我的代码:
def merge(left, right, aux=[]):
if left == []:
for x in right:
aux.append(x)
return aux
elif right == []:
for x in left:
aux.append(x)
return aux
elif left[0] > right[0]:
aux.append(right[0])
return merge(left, right[1:], aux)
else:
aux.append(left[0])
return merge(left[1:], right, aux)
def msort(values):
size = len(values)
if size == 1:
return values
else:
mid = size/2
return merge(msort(values[:mid]), msort(values[mid:]), [])
在这些测试列表上运行msort
可以得到预期的(升序)输出:
val = [x for x in range(1950, 0, -1)
val = [x for x in range(4,0,-1)]
e.g。 [1,2,3,......,1948,1949,1950]和[1,2,3,4]
但是,当我在此测试用例上运行msort
时:
val = [x for x in range(2000,0,-1)]
我现在收到此错误(经过多次追溯到merge
):
RuntimeError: maximum recursion depth exceeded in cmp
所以我的问题是:我的实施在这里出了什么问题?我不能将它用于N~> = 2000的列表。为什么呢?
答案 0 :(得分:4)
问题是你以递归方式进行合并。正如所指出的那样,可以调用merge(msort(left),msort(right))
,但由于你的merge
函数实际上会调用自己来进行合并,所以你会达到递归限制。
考虑在长度为1000的列表上调用merge
函数。
要合并这些列表,您需要进行2000次合并调用(因为每次调用只需要向aux
添加〜1个元素)。
答案 1 :(得分:2)
您的合并函数使用具有限制的递归。
如果你迭代而不是重复,你就绕过这个:
def merge(left, right, aux=[]):
while left and right:
if left[0] > right[0]:
aux.append(right.pop(0))
else:
aux.append(left.pop(0))
aux.extend(right)
aux.extend(left)
return aux
这是用法的一个例子:
>>> merge([1,3,5,7], [3,4,5,6])
[1, 3, 3, 4, 5, 5, 6, 7]
答案 2 :(得分:0)
答案 3 :(得分:0)
Python有递归限制。您可以使用以下方法设置最大值(小心):
import sys
sys.setrecursionlimit(MAXRECURSION)
我能够运行你的列表
val = [x for x in range(2000,0,-1)]
MAXRECURSION为2500