【问题标题】:count inversions in mergesort python在mergesort python中计算反转
【发布时间】:2018-09-08 23:23:39
【问题描述】:

我想在使用合并排序对列表进行排序时计算列表中有多少反转。到目前为止,这是我的代码,其中“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 支持给出列表中的反转数量。因此,如果列表为 '[4,3,2,1],x 将为 6。如果列表为 [1,2,3],x 将为 0。只要右边大于但是,留在合并定义中的数字总是太大了。我做错了什么?

【问题讨论】:

  • “反转”是什么意思?还有你想用x += len(L[first + 1:])做什么?
  • @Isac 所以反转就像每对的倒序一样。像 [10,8] 是一个倒置,因为它是倒序/降序。对于该行,我正在尝试计算整个反转列表。

标签: python python-3.x


【解决方案1】:

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

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

你想要的:

x += middle + 1 + j - k

基本上,您想要添加项目 k 实际来自何处与您期望它来自何处(如果所有内容都已排序)之间的差异。

【讨论】:

    【解决方案2】:

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

    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:]) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-14
      • 1970-01-01
      • 1970-01-01
      • 2010-09-25
      相关资源
      最近更新 更多