首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Python中的合并排序算法中计算掉期

如何在Python中的合并排序算法中计算掉期
EN

Stack Overflow用户
提问于 2017-12-31 10:17:41
回答 2查看 2.7K关注 0票数 1

我已经做了MergeSort算法,但我不知道如何计算掉期。

我的代码是:

代码语言:javascript
复制
def mergesortInv(list):
    if len(list) < 2:
        return list
    else:
        middle = len(list) // 2
        left = mergesortInv(list[:middle])   #definim les dues meitats
        right = mergesortInv(list[middle:])
        swaps=???       
    return mergeInv(left, right,swaps)

def mergeInv(left, right,swaps):
    if len(left) < 1:
        return right
    if len(right) < 1:
        return left
    if left[0] <= right[0]:
        return [left[0]] + mergeInv(left[1:],right,swaps)
    else:
        return [right[0]] + mergeInv(left,right[1:],swaps)

该算法的输出将是排序列表(算法在本部分中工作),交换的数量:mergesortInv(list) == ([1, 2, 3, 4, 5, 7, 8], 6) 6是交换的数量。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-12-31 10:38:25

下面是一个稍微修改过的代码版本,看起来很好用:

代码语言:javascript
复制
def mergesortInv(list, mergeInv):
    if len(list) < 2:
        return list, 0
    else:
        middle = len(list) // 2
        left, lc = mergesortInv(list[:middle], mergeInv)   #definim les dues meitats
        right, rc = mergesortInv(list[middle:], mergeInv)
    merge, mc = mergeInv(left, right)
    return merge, lc + rc + mc

def mergeInvRec(left, right):
    if len(left) < 1:
        return right, 0
    if len(right) < 1:
        return left, 0
    if left[0] <= right[0]:
        res, cnt = mergeInvRec(left[1:], right)
        return [left[0]] + res, cnt
    else:
        res, cnt = mergeInvRec(left, right[1:])
        return [right[0]] + res, len(left) + cnt

def mergeInvFlat(left, right):
    res, cnt = [], 0
    il, ir = 0, 0
    nl, nr = len(left), len(right)
    while il < nl and ir < nr:
        if left[il] <= right[ir]:
            res.append(left[il])
            il += 1
        else:
            res.append(right[ir])
            ir += 1
            cnt += nl - il
    res.extend(left[il:])
    res.extend(right[ir:])
    return res, cnt

这主要是簿记的问题。计算每个步骤的掉期数量,并将它们相加。在最后一个分支中,right的第一个元素一直在left的每个元素之后出现气泡,这就是为什么我们在那里统计len(left)掉期的原因。

编辑: As @PM2Ring指出,mergeInv中的递归有点鲁莽,对于中等大小的列表,它将超过mergeInv的最大递归深度。我添加了一个非递归版本。您可以在递归版本和非递归版本之间切换,方法是将它们的名称作为第二个arg传递给主函数。

票数 3
EN

Stack Overflow用户

发布于 2017-12-31 10:44:47

我没有测试这个,但这只是想让你知道我在对你的问题的评论中建议了些什么。

代码语言:javascript
复制
def mergesortInv(list):
    if len(list) < 2:
        return list
    else:
        middle = len(list) // 2
        left = mergesortInv(list[:middle])   #definim les dues meitats
        right = mergesortInv(list[middle:])
        # swaps=???
    return mergeInv(left, right)

def mergeInv(left, right):
    """ return a tuple of total swaps and the merged list """
    if len(left) < 1:
        return (0, right)
    if len(right) < 1:
        return (0, left)
    if left[0] <= right[0]:
        swaps, lst = mergeInv(left[1:],right)
        return (swaps, [left[0]] + [lst])
    else:
        swaps, lst = mergeInv(left,right[1:])
        return (swaps + 1, [right[0]] + [lst])

使用,

代码语言:javascript
复制
swaps, lst = mergesortInv(mylist)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48041639

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档