快速排序分治法返回不正确的部分答案

Posted

技术标签:

【中文标题】快速排序分治法返回不正确的部分答案【英文标题】:quicksort divide-and-conquer returns incorrect partial answer 【发布时间】:2014-10-13 03:26:34 【问题描述】:

我的程序最终没有返回正确的问题,但在中间结果中显示了正确的问题。我需要帮助,谢谢。

输出样本:

sort begin: A,start,end [3, 5, 2, 1, 7, 6, 8, 4] 0 7

sort begin: A,start,end [2, 1, 3, 5, 7, 6, 8, 4] 0 1

sort begin: A,start,end [1, 2, 3, 5, 7, 6, 8, 4] 3 7

sort begin: A,start,end [1, 2, 3, 4, 5, 6, 8, 7] 3 3

sort begin: A,start,end [1, 2, 3, 4, 5, 6, 8, 7] 5 7

sort begin: A,start,end [1, 2, 3, 4, 5, 6, 8, 7] 5 4

sort begin: A,start,end [1, 2, 3, 4, 5, 6, 8, 7] 6 7

####################################################


final result [1, 2, 3, 5, 4, 6, 8, 7]

我的代码:

def qSort(A,start,end):
    print "sort begin: A,start,end",A,start,end
    if start >= end:
        return A
    elif end == start + 1:
        if A[start] > A[end]:
            A[start],A[end] = A[end],A[start]
        return A
    else:
        i = start + 1
        j = i
        p = A[start]
        while j < end:
            j = j + 1
            if p > A[j]:
                A[i],A[j] = A[j],A[i]
                i = i + 1
        A = A[0:start] + A[start+1:i]+ [p] + A[i:end+1]

        qSort(A,start,i-2)
        qSort(A,i,end)
        return A

print "###################"
myarray = [3,5,2,1,7,6,8,4]

result = qSort(myarray,0,7)
print "final result",result

【问题讨论】:

一行快速排序qsort1 = lambda lst : lst if len(lst) &lt;= 1 else qsort1([i for i in lst[1:] if i &lt; lst[0]]) + [lst[0]] + qsort1([i for i in lst[1:] if i &gt;= lst[0]])复制自特鲁波对***.com/questions/228181/the-zen-of-python的评论 我打不过......刚开始用python T_T......还是不知道我的代码有什么问题......或者肯定是两个部分代码。递归的和摘要的? 这些可以帮助您找到问题! en.literateprograms.org/Quicksort_(Python) 【参考方案1】:

对不起,我缺乏光泽。我查看了您的代码并意识到它是正确的!你有一个小的编码错误,我会指出然后解释。在您当前拥有的 else 块中:

else:
    # Bunch of correct stuff
    # ...  
    # Stuff that is ALMOST correct
    qSort(A,start,i-2)
    qSort(A,i,end)
    return A

您需要将其更改为:

else:
    # Bunch of correct stuff
    # ...  
    # Stuff that is definitely correct
    A = qSort(A,start,i-2)
    A = qSort(A,i,end)
    return A

无需深入研究,您的函数不会区分列表引用和新创建的列表。如果您将print A 放入elif 块中return A 之前,您会注意到在最后一次迭代中,您的排序按原样正确执行所有操作,并生成正确的列表!

不幸的是,产生这种变化的调用是我上面提到的调用排序但不存储递归函数调用返回的结果列表的行之一!

我的简单更改只是将从辅助函数调用返回的修改后的列表带到 qSort 并重新分配变量 A。

奇怪的是,有时由于我无法完全解释的原因,这种行为实际上对你来说没问题(比如你第一次进入你的 `elif' 块,它做了正确的事情并正确地修改了列表)。我相信比我更聪明的人肯定可以解释这种奇怪的行为。

或者,您可以想出一个简单的方法来计算递归深度(您的函数调用自身的次数)并在您最喜欢的 IDE 中使用一些断点进行调试时将其打印出来。

以下是如何使用全局变量来做到这一点:

recursion_depth = -1

def qSort(A,start,end):
    global recursion_depth
    recursion_depth += 1
    print "sort begin: A,start,end,level",A,start,end,recursion_depth
    # bunch of code edited out for brevity
    # ...

result = qSort(myarray,0,7)
print "final result",result

【讨论】:

我尝试了您的更新,但它失败了,就像您将输入增加到更大的数组时一样(我之前的案例只是运气)。这是一些调试信息。 A = qsort(a,start,i-2) index error: list index out of range ...抱歉***不允许我粘贴... 能贴一下失败的测试用例吗?

以上是关于快速排序分治法返回不正确的部分答案的主要内容,如果未能解决你的问题,请参考以下文章

算法学习---分治法和快速排序

快速排序(分治法)

排序算法之快速排序

快速排序算法

经典算法之快速排序

排序5:快速排序