【问题标题】:Mergesort return no longer in order合并排序不再按顺序返回
【发布时间】:2016-12-20 02:46:31
【问题描述】:

我不是初学者,但我也不是高级程序员。如果您可以查看我所描述的内容,则该问题将更容易解释。这是我看到问题的代码:

import operator

def mergeSort(L, compare = operator.lt):
    if len(L) < 2:
        return L[:]
    else:
        middle = int(len(L)/2)
        left = mergeSort(L[:middle], compare)
        right = mergeSort(L[middle:], compare)
        return merge(left, right, compare)

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

合并功能有效。最终的返回结果总是有序的。问题是,如果从最后的返回结果往前走一步,返回到mergesort中的return merge(left, right, compare),返回的列表L就不再有序了,然后把这个乱序的列表返回到调用合并排序的函数。我什至不明白为什么会这样。从返回结果到返回合并(左,右,比较)的返回行程会发生什么?返回的列表不是随机列表,它看起来像是一个部分排序的列表,但在最终返回结果中是完全排序的,而且这个结果不是返回给mergesort的。

我之前使用过这个合并排序没有问题,所以问题可能出在我正在排序的数据中。 L 是一个列表列表,每个列表元素都是一个字符串列表,长度相同,要导出到 csv 并最终导出到 Excel。我的数据是一个表格,第一列是网站标题,第二列是网址,我正在对它们进行排序以识别重复项。完整的表中还有其他几个字段,但我看到这个问题只有 title 和 url 列,这是我简化的,所以我可以尝试看看出了什么问题。我不确定mergesort 是否可以处理这种数据结构,但是merge 中的最终返回结果肯定表明它可以。但是在最后的回归中发生了一些神秘的事情。

【问题讨论】:

  • 如果您对某些类型的数据有疑问,请添加有问题的示例数据,以便每个人都可以运行它并查看问题。
  • 有没有办法将文件附加到我的帖子中?在看到这种情况发生之前,您需要相当多的数据行。我在帖子中添加了数据描述

标签: python function mergesort


【解决方案1】:

似乎没有保存合并的结果。这是一个修复:

def mergeSort(L, compare = operator.lt):
    if len(L) < 2:
        return L[:]
    else:
        middle = int(len(L)/2)
        left = mergeSort(L[:middle], compare)
        right = mergeSort(L[middle:], compare)
        L[:] = merge(left, right, compare)
    return L

【讨论】:

  • 很抱歉,我尝试了您的修复方法,但没有成功。事实上,列表现在看起来更加随机,不像是部分排序的。我还确认了我之前看到的,在最后一个返回结果执行之前列表是有序的,但是当它返回到 mergesort 并且在 merge(left, right, compare) 执行之前它是无序的。这两个步骤之间可能会发生什么?
【解决方案2】:

我最终写了the python.org list 来讨论这个问题,而我得到的第一个回复就一针见血:

2016 年 12 月 22 日星期四上午 11:55,黛博拉·斯旺森写道:

问题在于,虽然 mergeSort 将列表 ls 以完美的顺序排列, 我可以通过查看合并最终返回的结果来看到 mergeSort,并在左右一次返回mergeSort。两个都 左半边和右半边是有序的。但是列表 L 仍然是 按照原来的顺序,在 mergeSort 完成后, ls 仍然在 它的原始顺序。也许有一些愚蠢的错误导致了这个, 但我就是看不到。

您的分析非常出色。以下是发生的情况:当您进行合并排序时,您总是返回一个新列表(“return L[:]”或“result = []”),但您可以这样称呼它:

# sort: Description only, to make hyperelinks & find duplicates
mergeSort(ls)

这会调用mergeSort,然后将新排序的列表放在地板上。相反,请尝试:“ls = mergeSort(ls)”。

感谢您让我们如此轻松!

克里斯A

因此,可以使用合并排序对列表列表进行排序,这是我直到现在才确定的。

【讨论】:

  • 没问题 dmars,很高兴我能帮上忙。 (那是我在邮件列表中。)
猜你喜欢
  • 2021-09-16
  • 2013-04-02
  • 2018-04-29
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多