我是python的新手,我正在尝试在Python中实现merge_sort,这是我的代码。但它进入无限循环。任何人都可以指出为什么?感谢
def merge_sort(a):
'''implement merge sort for array'''
l = len(a)
if l == 1:
return a[0]
a1 = merge_sort(a[:l/2-1])
a2 = merge_sort(a[l/2:-1])
a_sort = []
idx1, idx2 = 0, 0
#for i in range(l):
if idx1 == len(a1):
a_sort.append(a2[idx2:])
import ipdb; ipdb.set_trace()
return a_sort
elif idx2 == len(a2):
a_sort.append(a1[idx1:])
return a_sort
else:
if a1[idx1] >= a2[idx2]:
a_sort.append(a2[idx2])
idx2 += 1
else:
a_sort.append(a1[idx1])
idx1 += 1
答案 0 :(得分:0)
问题是当你的递归到达一个空列表(即l == 0
)时,你会在返回任何内容之前两次调用merge_sort([])
。您需要添加if l == 0: return []
。
另外,您对if l == 1: return a[0]
的检查有点不对劲; merge_sort
应始终返回一个列表,而这将返回一个列表元素(数字或字符串或其他)。所以它应该只是
if l <= 1:
return a
另外,您的a2
实际上不包含数组的最后一个元素:您需要a[l/2:]
,而不是a[l/2:-1]
。 (请记住,Python中的范围不包含最后一个元素。)
这不会影响代码的正确性,但您应该使用l // 2
来表示整数除法;在Python3中,如果你from __future__ import division
l/2
,l
是奇数。
答案 1 :(得分:0)
正如Dougal和Andrei指出的那样,无限循环是由未经检查的边缘条件引起的。将行if l == 1:
替换为if l < 2:
代码中还有其他问题:
a
的左侧部分和右侧部分l/2
位置对应a[:l/2]
和a[l/2:]
。没有必要减去1.只要认为一个位置在两个项目之间。.extend()
和append()
分支if
代替elif
return
通常while
结构更方便
while idx1 < len(a1) and idx2 < len(a2):
'code in your else branch'
if idx1 < len(a1):
a_sort.extend(a1[idx1:])
else:
a_sort.extend(a2[idx2:])
return a_sort
答案 2 :(得分:0)
谢谢!工作代码如下
def merge_sort(a):
'''implement merge sort for array'''
l = len(a)
if l == 1:
return a
a1 = merge_sort(a[:l//2])
a2 = merge_sort(a[l//2:])
a_sort = []
idx1, idx2 = 0, 0
while idx1 < len(a1) and idx2 < len(a2):
if a1[idx1] >= a2[idx2]:
a_sort.append(a2[idx2])
idx2 += 1
else:
a_sort.append(a1[idx1])
idx1 += 1
if idx1 < len(a1):
a_sort.extend(a1[idx1:])
else:
a_sort.extend(a2[idx2:])
return a_sort