我正在学习快速排序算法,但由于某种原因,这个python实现的输出只是部分排序,并且我得到了“更大输入的'最大递归深度'。在过去的几天里,我一直在反对这一点,我知道这可能是非常愚蠢的事情,但我似乎无法弄明白,所以我会感激任何帮助。
def ChoosePivot(list):
return list[0]
def Partition(A,left,right):
p = ChoosePivot(A)
i = left + 1
for j in range(left + 1,right + 1): #upto right + 1 because of range()
if A[j] < p:
A[j], A[i] = A[i], A[j] #swap
i = i + 1
A[left], A[i - 1] = A[i-1], A[left] #swap
return i - 1
def QuickSort(list,left, right):
if len(list) == 1: return
if left < right:
pivot = Partition(list,left,right)
QuickSort(list,left, pivot - 1)
QuickSort(list,pivot + 1, right)
return list[:pivot] + [list[pivot]] + list[pivot+1:]
sample_array = [39,2,41,95,44,8,7,6,9,10,34,56,75,100]
print "Unsorted list: "
print sample_array
sample_array = QuickSort(sample_array,0,len(sample_array)-1)
print "Sorted list:"
print sample_array
答案 0 :(得分:2)
不确定这是问题,但你错误地选择了枢轴:
def ChoosePivot(list):
return list[0]
def Partition(A,left,right):
p = ChoosePivot(A)
....
您总是占据原始列表的头部,而不是修改后列表的头部。
假设在某些时候你将范围缩小到left = 5,right = 10 - 你选择list [0]作为支点 - 这可能不是很好。
因此,在left>0
的每次迭代中,您忽略列表中的第一个元素,并“忽略”它 - 这可以解释部分排序
答案 1 :(得分:1)
def ChoosePivot(list):
return list[0]
正如amit所说,这是错误的。你想要p = A[left]
。但是,还有另一个问题:
if A[j] < p:
A[j], A[i] = A[i], A[j] #swap
i = i + 1
只有在交换时才会递增数据透视索引。将i = i + 1
缩进到与交换相同的深度,作为if
语句的一部分。
奖金问题:你为什么要分区两次?
答案 2 :(得分:0)
也是最后一次交换;
A [左],A [i - 1] = A [i-1],A [左] #swap
应该使用pivot。
此外Quicksort的工作原理。所以你不需要关注返回;
返回列表[:pivot] + [list [pivot]] + list [pivot + 1:]
答案 3 :(得分:-1)
不完全是您问题的答案,但我认为它仍然是最相关的。
在实施快速排序时,选择一个始终位于相同位置的枢轴是算法的一个缺陷。可以生成一系列数字,使您的算法在O(n ^ 2)时间运行,绝对运行时间可能比bubblesort更差。
在你的算法中,选择最左边的项会使算法在数组已经排序或接近排序的最坏情况下运行。
应该随机选择枢轴以避免此问题。
检查维基百科中算法的实施问题:http://en.wikipedia.org/wiki/Quicksort#Implementation_issues
实际上,检查孔文章。值得你花时间。