我正在研究一个作业问题,该问题是使用称为分区的助手功能并使用递归来创建快速排序算法。我的代码正在引发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
答案 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 ≥ 0
:n
上加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))