Python-Merge排序困难

时间:2015-01-24 05:04:22

标签: python mergesort

我尝试实现合并排序,这是我的代码:

def mergeSort(array):
    result=[]
    n=len(array)
    if n==1:
        result=array
    else:
        a=round(n/2)
        first=mergeSort(array[0:a])
        second=mergeSort(array[a:n])

        for i in range(len(first)):
            for j in range(len(second)):
                if first[i]<second[j]:
                    result.append(first[i])
                    i=i+1
                else:
                    result.append(second[j])
                    j=j+1
    return result

a=[5,4,1,8,7,6,2,3]
b=mergeSort(a)
print(b)

不幸的是,结果证明是[1]。我的功能出了什么问题?

1 个答案:

答案 0 :(得分:4)

很多事情......

首先,这是一个递归函数,这意味着你不能像在这里一样在函数中创建一个列表:

result=[]

这会在每次递归调用后重置您的列表,从而扭曲您的结果。最简单的方法是更改​​作为参数传递的列表以合并排序。

你的下一个问题是你在for循环中有一个for循环。这不起作用,因为当第一个for循环迭代first时,第二个for循环将针对second的每个增量迭代i,这不是你想要的。您需要的是比较firstsecond并提取最小值,然后提取下一个最小值,依此类推,直到获得排序列表。 所以你的for循环需要改为:

while i < len(first) and j < len(second):

这导致我在您的代码中遇到最终问题。在满足其中一个条件后,while循环将退出,这意味着ij(一个或另一个)将不会达到len(first)len(second)。换句话说,firstsecond中有一个值是未计入的值。您需要将此未计入值添加到已排序列表中,这意味着您必须在函数末尾实现此最终摘录:

remaining = first if i < j else second
r = i if remaining == first else j

while r < len(remaining):
    array[k] = remaining[r]
    r = r + 1 
    k = k + 1

此处r表示前一个while循环中断的索引值。然后while循环将遍历剩余的剩余值;将它们添加到排序列表的末尾。

现在,合并排序应如下所示:

def mergeSort(array):
    if len(array)==1:
        return array
    else:
        a=round(len(array)/2)
        first=mergeSort(array[:a])
        second=mergeSort(array[a:])
        i = 0
        j = 0
        k = 0
        while i < len(first) and j < len(second):
            if first[i]<second[j]:
                array[k] = first[i]
                i=i+1
                k=k+1
            else:
                array[k] = second[j]
                j=j+1
                k=k+1

        remaining = first if i < j else second
        r = i if remaining == first else j

        while r < len(remaining):
            array[k] = remaining[r]
            r += 1; k += 1

    return array

我尽量不改变您的代码,以便您更容易理解。但是,如果您难以理解我所做的事情,请尝试使用多个打印语句来修改合并排序,以便您可以按照函数的进度查看它出错的位置。