合并排序问题 - Python

时间:2013-02-08 17:14:04

标签: python algorithm sorting merge

我的代码出了什么问题?它只打印vect值的一部分。似乎while循环在某个时刻中断。我不明白为什么。

def print_list(vect):
    for i in range(0, len(vect)):
        print(vect[i])

def merge_sort(vect):
    left = []
    right = []    
    result = []

    for i in range(0, int(len(vect)/2)):
        left.append(vect[i])
    for i in range(int(len(vect)/2), len(vect)):
        right.append(vect[i])

    left.sort()
    right.sort()
    i = 0
    j = 0

    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1

    print(len(result))
    return result

vect = [3, 1, 5, 7, 10, 2, 0]

vect = merge_sort(vect)

2 个答案:

答案 0 :(得分:5)

嗯,你的错误就是在你的while循环之后

while i < len(left) and j < len(right):
  ...

它可能(并且很可能会)i < len(left)j < len(right),因此您需要在答案中附加适当的部分后缀。用

很容易
result += left[i:]
result += right[j:]

<强>解释

想象一下合并程序:你有i和j在开始时为0,并且在每一步你都向前移动其中一个。当你停下来?当其中一个到达终点时。让我们说我已经到了尽头。因此,您将整个左侧部分添加到结果中,但是在j和len(右侧)之间仍然存在一些元素,因此您还必须将它们添加到答案中。

<强> Offtop

您正在实施合并排序,请

left = merge_sort( left )
right = merge_sort( right )

而不是

left.sort()
right.sort()

注意:您必须在合并函数开头的代码中添加以下检查,以避免无限递归:

if len( vect ) == 1:
   return vect

同样在你的print_list函数中,你可以使用

print vect

或至少

for x in vect
print x

答案 1 :(得分:3)

只要左或右用尽,while循环就会退出。这使得未清除列表中剩余的所有元素都保持未合并状态。

将您的代码更改为:

def print_list(vect):
    for i in range(0, len(vect)):
        print(vect[i])

def merge_sort(vect):
    left = []
    right = []

    result = []
    for i in range(0, int(len(vect)/2)):
        left.append(vect[i])
    for i in range(int(len(vect)/2), len(vect)):
        right.append(vect[i])

    left.sort();
    right.sort();
    i = 0
    j = 0

    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1

    if i < len(left):
        result.extend(left[i:])
    else:
        result.extend(right[j:])

    print(len(result))
    return result

vect = [3, 1, 5, 7, 10, 2, 0]

vect = merge_sort(vect)
print vect

如果你在左右使用排序方法,我有点困惑为什么你不只是在整个列表中使用它。但我想你有理由。 :)

编辑:我将整个代码块放在那里,以便您可以看到它。当我运行它时,它打印[0,1,2,3,5,7,10],这是正确的。