在mergesort python

时间:2018-03-29 21:57:38

标签: python python-3.x

我想计算使用mergesort对列表进行排序时列表中有多少个反转。到目前为止,这是我的代码,其中' x'计算倒数的大小,而其余的则对其进行排序:

import sys
x = 0

def merge_sort(A):
    merge_sort2(A, 0, len(A) - 1)


def merge_sort2(A, first, last):
    if first < last:
        middle = (first + last) // 2
        merge_sort2(A, first, middle)
        merge_sort2(A, middle + 1, last)
        merge(A, first, middle, last)


def merge(A, first, middle, last):
    global x
    L = A[first:middle + 1]
    R = A[middle + 1:last + 1]
    L.append(sys.maxsize)
    R.append(sys.maxsize)
    i = j = 0

    for k in range(first, last + 1):
        if L[i] <= R[j]:
            A[k] = L[i]
            i += 1
        else:
            A[k] = R[j]
            j += 1
            x += 1
            x += len(L[first + 1:])

当我使用列表调用合并排序时,变量x支持在列表中给出反转量。所以如果列表是&#39; [4,3,2,1],x将是6.如果列表是[1,2,3] x将是0.我改变x的值只要右边是但是,在合并定义中大于左边的数字总是太大了。我做错了什么?

2 个答案:

答案 0 :(得分:0)

检查我的工作,但我认为不是:

x += 1
x += len(L[first + 1:])

你想要:

x += middle + 1 + j - k

基本上,你想要添加项目k实际来自哪里之间的差异,以及如果所有内容都已经排序,你希望它来自哪里。

答案 1 :(得分:0)

您的合并步骤对我来说有点难以理解 - 我不确定您为什么这样做(也许只是另一种合并方式?):

L.append(sys.maxsize)
R.append(sys.maxsize)

但是我无法通过添加到分区的额外元素来解决所有问题。而且我认为你最终将L中的额外元素作为反转进行计数,每次合并都从R

移开

我认为这会导致一些问题。但是你还有另外两个问题:

你的最后一行不是正确的逻辑:

 x += len(L[first + 1:])

反转的数量将是你跳过的L中的元素数量。你每次都计算L的几乎所有元素。这样的事情效果更好:

x += len(L[i:]) 

然后在最后,你可能还剩下你还没有计算过的倒数的元素。也许这不是你的额外元素的问题,而是在更传统的合并中。这是我计算反转的方式:

def merge(A, first, middle, last):
    global x
    L = A[first:middle+1]
    R = A[middle+1:last+1]
    i = j = 0
    k = first
    print(L, R)
    while i<len(L) and j<len(R):
        if L[i] <= R[j]:
            A[k] = L[i]
            i += 1
        else:
            A[k] = R[j]
            j += 1
            # count how many left in L 
            x += len(L[i:]) 
        k += 1
    # take care of any leftovers in L or R
    while i < len(L):
        A[k] = L[i]
        i += 1
        k+=1
    while j < len(R):
        A[k] = R[j]
        j += 1
        k+=1
        x += len(L[i:])