问题描述
我尝试编写就地快速排序,但无法正确返回排序后的数组。根据print语句的输出,该算法似乎确实在对数组进行排序,但我似乎无法返回已排序的数组。我以为会进行排序,但似乎没有,而且我不确定如何解决此问题。
def quicksort(array):
if len(array) <= 1:
return
pivot = len(array) - 1
i = 0
while i < pivot:
if array[i] > array[pivot]:
if i == pivot - 1:
array[i],array[pivot] = array[pivot],array[i]
array[pivot],array[pivot-1] = array[pivot-1],array[pivot]
pivot -= 1
array[i],array[pivot+1] = array[pivot+1],array[i]
else:
i += 1
print(array)
quicksort(array[:pivot]) # sorts lower
quicksort(array[pivot:]) # sorts upper
return array
test = [21,4,1,3,9,20,25,6,21,14]
print quicksort(test)
解决方法
这里的问题是您要切片list
,该切片会返回副本而不是视图。因此,您的每个递归调用都会对一个副本而不是原始列表进行排序。我建议您使用numpy.array
作为输入以执行就地快速排序。实际上,对numpy.array
进行切片(基本)会返回a view。这是最接近规范数组的python数据结构。
进行递归调用quicksort(array[:pivot])
时,不会将原始列表传递给quicksort()
,而是创建一个新列表。
为避免创建新列表,可以删除slice语法,而是将数组索引传递给函数:
def quicksort(array,start,length):
if length <= 1:
return
pivot = start + length - 1
i = start
while i < pivot:
if array[i] > array[pivot]:
if i == pivot - 1:
array[i],array[pivot] = array[pivot],array[i]
array[pivot],array[pivot-1] = array[pivot-1],array[pivot]
pivot -= 1
array[i],array[pivot+1] = array[pivot+1],array[i]
else:
i += 1
print(array[start:start+length])
quicksort(array,pivot-start) # sorts lower
quicksort(array,pivot,length-pivot) # sorts upper
return array
test = [21,4,1,3,9,20,25,6,21,14]
print quicksort(test,len(test))