【问题标题】:Merge sort in python doesnt update the array after sortingpython中的合并排序在排序后不会更新数组
【发布时间】:2015-05-24 15:51:18
【问题描述】:
ab = [5, 89, 23, 9]

def mergsort(array):        
    mid = len(array) / 2
    if mid > 0:
        print (array)
        mergsort(array[:mid])
        mergsort(array[mid:])
        print(array)
        merg(array)
    return array

def merg(array):
    print (array)
    mid = len(array)//2
    left = array[:mid]
    right = array[mid:]
    i = j = k = 0

    while i < len(left) and j < len(right):
        if left[i] < right[j]:
            array[k] = left[i]
            i+=1

        else:
            array[k] = right[j]
            j+=1
        k+=1

    while i < len(left):    
        array[k]=left[i]
        i+=1
        k+=1

    while j < len(right):    
        array[k] = right[j]
        j+=1
        k+=1
    print (array)

mergsort(ab)
print (ab)

merge 函数对给定的数组进行排序并更新数组。但在下一次递归中,进入merg 函数的数组不是变异数组。

在示例中,首先进行排序,[5,89][23,9] 被排序为 [5,89][9,23],但下一次递归中的合并输入是 [5,89,23,9] 而不是 [5,89,9,23]

我找不到任何原因,因为改变数组会影响父数组。

【问题讨论】:

    标签: python sorting recursion merge


    【解决方案1】:

    一个问题是递归调用:

        mergsort(array[:mid])
        mergsort(array[mid:])
    

    这些调用的结果不会被记录 - 所以当我们继续时,它会使用相同的原始未排序数组。

    修复:

    def mergsort(array):     
        if len(array) == 1:
            return array
        mid=len(array)/2
        left = mergsort(array[:mid])  # save into a parameter
        right = mergsort(array[mid:])  # save into a parameter
        return merge(left, right)  #  use the previous two
    

    第二个问题实际上是同一类型的问题,只是:

    def merg(array)
    

    合并操作是在两个数组之间完成的,这意味着应该将两个不同的数组发送给这个函数,否则不会从函数mergesort()中回收mid并将mid声明为length/2处理整个数组,而不是我们打算合并的特定两个部分。此函数内部逻辑背后的想法是正确的,但正如我所提到的,应该在两个“不同”数组上完成。

    最后一个问题是不正确的就地交换,例如:

    array[k]=right[j]
    

    通过这样做,我们删除了 array[k]! 处的元素!

    修复:

    def merge(left, right):
        if  len(left+right) < 2:
            return left+right
        res = []
        i = j = 0
        while i < len(left) and j < len(right):
            if left[i] < right[j]:
                res.append(left[i])
                i += 1
            elif j < len(right):
                res.append(right[j])
                j += 1        
        while i < len(left):
            res.append(left[i])
            i += 1
        while j < len(right):
            res.append(right[j])
            j += 1
        return res
    

    应用两个修复程序并运行后:

    print mergsort(ab)
    

    输出是:

    [5, 9, 23, 89]
    

    根据需要。

    【讨论】:

    • 嘿.. 感谢您的清晰解释。但是我的一个疑问是,当我在合并函数中修改列表变量时,不会自动更新合并排序中的数组。我可以看到它不会发生,它不会发生。但是不明白为什么?
    • @user32175 请再读一遍我的解释,特别注意谈论你传递给merge的部分以及merge如何“知道”左右部分它应该处理。
    猜你喜欢
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 2011-07-23
    • 1970-01-01
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    相关资源
    最近更新 更多