然后使用快速排序使用了分而治之(divide and conquer,D&C)的思想
主要思想就是把一个无序数组分为3个部分:递归的思想重复以上步骤
- 中心点(pivot):该点是随机选的,一般选数组中索引为0,即第一个数当中心点
- 左边(less):小于等于中心点的数组成的数组
- 右边(greater):大于中心点的数组成的数组
参考算法图解给出的代码
#quicksort
def quick_sort(arr):
if len(arr) < 2:
return arr
else:
pivot = arr[0]
less = [i for i in arr[1:] if i <= pivot]
greater = [i for i in arr[1:] if i > pivot]
return quicksort(less)+[pivot]+quicksort(greater)
if __name__ == '__main__':
test = [49, 38, 65, 97, 76, 13, 27, 49]
print(quick_sort(test))
中间使用了两次循环,虽然在时间复杂度上没有任何变化,但实际时间不如使用一次循环
#quicksort
def quicksort(arr):
if len(arr) < 2:
return arr
else:
less = []
greater = []
pivot = arr[0]
for i in arr[1:]:
if i <= pivot:
less.append(i)
else:
greater.append(i)
return quicksort(less)+[pivot]+quicksort(greater)
if __name__ == '__main__':
test = [49, 38, 65, 97, 76, 13, 27, 49]
print(quicksort(test))
在平均情况下,快速排序的时间复杂度为O(nlogn)
最坏情况下,快速排序的时间复杂度为O(n^2)
至于为什么有的时候复杂度为O(nlogn),有的时候复杂度为O(n^2)?这和选择的基准值,即pivot有关。
最坏的情况下会递归n次,即调用栈(call stack)的高度为n
而平均情况下,会递归logn次,即调用栈的高度为logn
还有一种排序算法的时间复杂度总是O(nlogn),这种排序算法即为合并排序
既然如此,为什么我们经常使用快速排序,而不使用合并排序?
下节在合并排序中一起讲解。