为什么我的QuickSort算法会出现RecursionError?

时间:2019-04-08 19:15:52

标签: python python-3.x

我正在研究一个作业问题,该问题是使用称为分区的助手功能并使用递归来创建快速排序算法。我的代码正在引发RecursionError,但我似乎无法弄清楚原因。

我尝试重新排序代码,但似乎无济于事。

def partition(L, p):

    newL = L.copy() # New list of the same size.
    i = 0 # Index for inserting small values.
    j = len(newL)-1 # Index for inserting large values.
    # Iterate through the elements in the old list.
    for ind in range(len(L)):
    # Skip the pivot.
        if ind != p:
            if L[ind] <= L[p]:
                newL[i] = L[ind] # If < pivot, place at i.
                i += 1 # Increment to next open space.
            else:
                newL[j] = L[ind] # If >= pivot, place at j.
                j -= 1 # Decrement to next open space.
    # Now i==j and this is the only open space.
    newL[i] = L[p] # Place the pivot in its spot.
    return (newL, i)


def QuickSort(L):
    if len(L)==0 or len(L)==1:
        return L
    else:
        pivot=L[0]
        newL=partition(L,pivot)[0]
        newPivot=partition(L,pivot)[1]
        L2=newL[newPivot:]
        L1=newL[:newPivot]
        L2=QuickSort(L2)
        L1=QuickSort(L1)
        L=merge(L1,L2)

    return L

if __name__ == '__main__':
    L=[1,0,2]
    print(QuickSort(L))
Traceback (most recent call last):
  File "/Users/ellavanengen/eclipse-workspace/hw1/src/hw7.py", line 108, in <module>
    print(QuickSort(L))
  File "/Users/ellavanengen/eclipse-workspace/hw1/src/hw7.py", line 97, in QuickSort
    L2=QuickSort(L2)
  File "/Users/ellavanengen/eclipse-workspace/hw1/src/hw7.py", line 97, in QuickSort
    L2=QuickSort(L2)
  File "/Users/ellavanengen/eclipse-workspace/hw1/src/hw7.py", line 97, in QuickSort
    L2=QuickSort(L2)
  [Previous line repeated 988 more times]
  File "/Users/ellavanengen/eclipse-workspace/hw1/src/hw7.py", line 93, in QuickSort
    newL=partition(L,pivot)[0]
  File "/Users/ellavanengen/eclipse-workspace/hw1/src/hw7.py", line 72, in partition
    for ind in range(len(L)):
RecursionError: maximum recursion depth exceeded in comparison

2 个答案:

答案 0 :(得分:1)

阻止QuickSort()退出递归的主要问题是:

        pivot=L[0]
        newL=partition(L,pivot)[0]
        newPivot=partition(L,pivot)[1]
        L2=newL[newPivot:]
        L1=newL[:newPivot]

首先,pivot必须使用列表中的 position 而不是列表中的 value 进行初始化。更正:

        pivot=0

第二,别忘了列表枚举以0开头,而列表 slicing list[:0]上产生一个空列表,而在{{ 1}}。要将列表切成元素#list[0:]n,请在n ≥ 0n上加1。列表尾部的处理类似。

如您所见,第一个递归调用始终会收到完整列表。

更正:

beginning = list[:n+1]

这两个是主要问题。以下是两个较小的缺点。

首先,返回元组的Python函数能够一次分配多个变量:

        L2=newL[newPivot+1:]
        L1=newL[:newPivot+1]

第二, (newL, newPivot) = partition(L,pivot) 的结果是一个迭代器,而不是列表。而且,毫无疑问,使用它会被视为作弊,因为无论如何它都会对结果列表进行排序。编写自己的heapq::merge()

答案 1 :(得分:0)

我对QuickSort algorithm in Wikipedia的理解是,您应该能够对数组进行排序,而不能进行类似newL = L.copy()的操作。并且您正在执行的merge()操作应该是一个更简单的连接,因为两个数组已经排序,所有值之一都比另一个低。遵循基本的 inplace 算法,我提出了类似的内容:

def partition(array, low, high):

    pivot = array[high]

    index = low

    for j in range(low, high):
        if array[j] < pivot:
            array[index], array[j] = array[j], array[index]
            index += 1

    array[index], array[high] = array[high], array[index]

    return index

def quicksort_recursive(array, low, high):
    if low < high:
        index = partition(array, low, high)

        quicksort_recursive(array, low, index - 1)
        quicksort_recursive(array, index + 1, high)

def quicksort(array):

    if len(array) > 1:

        quicksort_recursive(array, 0, len(array) - 1)

    return array

if __name__ == '__main__':
    array = [13, 5, 31, 63, 39, 61, 14, 19, 37, 93, 88, 55]
    print(quicksort(array))

但是,如果我们愿意浪费时间和空间来复制数组片段,而变得更Python化,则可以将其显着简化为:

def partition(array):

    pivot = array[0]

    low = []
    high = []

    for number in array[1:]:
        (low if number < pivot else high).append(number)

    return low, pivot, high

def quicksort(array):

    if len(array) > 1:

        low, middle, high = partition(array)

        return [*quicksort(low), middle, *quicksort(high)]

    return array

if __name__ == '__main__':
    array = [13, 5, 31, 63, 39, 61, 14, 19, 37, 93, 88, 55]
    print(quicksort(array))