python中的merge_sort

时间:2012-04-15 06:25:42

标签: python mergesort

我是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

3 个答案:

答案 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/2l是奇数。

答案 1 :(得分:0)

正如Dougal和Andrei指出的那样,无限循环是由未经检查的边缘条件引起的。将行if l == 1:替换为if l < 2: 代码中还有其他问题:

  • 列表a的左侧部分和右侧部分l/2位置对应a[:l/2]a[l/2:]。没有必要减去1.只要认为一个位置在两个项目之间。
  • .extend()append()分支
  • 中使用if代替elif
  • 不要忘记让评论出来的forloop回来。
  • 最后没有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