Mergesort不再按顺序返回

时间:2016-12-20 02:46:32

标签: python function mergesort

我不是一个初学的python编码器,但我也不是一个先进的编程器。如果你能看一下我所描述的内容,问题将更容易解释。这是我遇到问题的代码:

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中的返回合并(左,右,比较),返回的列表L不再有序,然后这个错误排序的列表返回到调用mergesort的函数。我甚至不明白为什么会这样。从返回结果到返回合并的返回行程会发生什么(左,右,比较)?返回的列表不是随机列表,它看起来像是一个部分排序的列表,但它在最终的返回结果中完全排序,并且这个结果不是返回到mergesort的结果。

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

我最后写了关于这个问题的the python.org list,并且第一个回复我的头上钉了一针:

2016年12月22日星期四上午11:55,Deborah Swanson写道:

  

问题是,当mergeSort将列表ls完美排序时,   通过查看合并最终返回的结果,我可以看到   mergeSort,并在mergeSort中返回左侧和右侧。都   左半部分和右半部分按顺序排列。但名单L仍然是   按原始顺序,在mergeSort完成后,ls仍在   它的原始订单。也许有一些骨头错误导致这种情况,   但是我无法看到它。

您的分析非常好。这里发生了什么:当你合并排序时,你总是会返回一个新的列表(&#34;返回L [:]&#34;或者&#34; result = []&# 34;),但是你这样称呼它:

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

这会调用mergeSort,然后在地板上删除新排序的列表。相反,请尝试:&#34; ls = mergeSort(ls)&#34;。

感谢您让我们这么容易!

ChrisA

因此,可以使用merge-sort对列表列表进行排序,直到现在我还不确定。