快速排序
快速排序是一种经典的排序算法,它的基本思想是通过一次排序将待排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
以下是使用 Python 实现的快速排序:
def quick_sort(arr):
if len(arr) <= 1:
return arr
else:
pivot = arr[0]
less = [x for x in arr[1:] if x <= pivot]
greater = [x for x in arr[1:] if x > pivot]
return quick_sort(less) + [pivot] + quick_sort(greater)
# 测试快速排序函数
arr = [3, 6, 8, 10, 1, 2, 1]
sorted_arr = quick_sort(arr)
print(sorted_arr) # 输出:[1, 1, 2, 3, 6, 8, 10]
这个 quick_sort
函数首先检查输入的数组 arr
的长度。如果 arr
的长度小于或等于 1,那么这个数组已经是排序好的,直接返回 arr
。
否则,函数选择 arr
的第一个元素作为基准值 pivot
,然后将 arr
中剩余的元素分成两组:一组包含所有小于或等于 pivot
的元素,另一组包含所有大于 pivot
的元素。
最后,函数对这两组元素递归地进行快速排序,然后将排序后的结果和 pivot
连接起来,得到最终的排序结果
-
在最好的情况和平均情况下,快速排序的时间复杂度是 O(n log n),其中 n 是待排序数组的长度。这是因为在这些情况下,快速排序大致上会将数组均匀地划分为两个子数组,所以每次划分的时间复杂度是 O(n),而划分的深度大约是 log n,所以总的时间复杂度是 O(n log n)。
-
在最坏的情况下,快速排序的时间复杂度是 O(n^2)。这是因为在最坏的情况下,例如当输入数组已经完全有序或完全逆序时,每次划分只能将数组划分为一个元素和 n-1 个元素两部分,这时划分的深度就是 n,所以总的时间复杂度是 O(n^2)。
值得注意的是,虽然快速排序在最坏情况下的时间复杂度是 O(n^2),但是在实际应用中,这种最坏情况并不常见,而且通过一些改进的策略,例如随机选择'轴点',可以显著减少最坏情况出现的概率。所以在实际应用中,快速排序通常被认为是一种非常高效的排序算法。
如果我们希望随机选择'轴点',我们可以稍微修改一下前面的代码。Python 的 random
模块有一个 randint
函数,我们可以使用它来生成一个随机的索引。以下是代码示例:
import random
def quicksort(arr):
if len(arr) <= 1:
return arr
else:
pivot_index = random.randint(0, len(arr) - 1) # 选择一个随机的索引作为轴点
pivot = arr[pivot_index]
arr = arr[:pivot_index] + arr[pivot_index+1:] # 从列表中移除轴点
less = [i for i in arr if i <= pivot]
greater = [i for i in arr if i > pivot]
return quicksort(less) + [pivot] + quicksort(greater)
# 测试
array = [12, 4, 5, 6, 7, 3, 1, 15]
print(quicksort(array))
在这个版本的快速排序中,我们随机选择'轴点',这样可以降低在最坏情况(如输入已排序的数组)下的可能性,使得算法在平均情况下达到 O(n log n) 的时间复杂度。