快速排序(QuickSort)是一种高效的排序算法,由C. A. R. Hoare在1960年提出。其基本思想是采用分治策略,通过一趟排序将待排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
以下是快速排序的基本步骤:
-
选择基准元素:从待排序的数列中选择一个元素作为基准(pivot)。
-
分区操作:重新排列数列,使所有比基准小的元素都出现在基准的左边,所有比基准大的元素都出现在基准的右边。这个操作称为分区操作(partition)。分区完成后,基准元素处于最终正确位置,即所有小于基准的元素都在其左侧,所有大于基准的元素都在其右侧。
-
递归排序:递归地对基准左边和右边的两个子序列分别进行快速排序。
时间复杂度:
- 最好情况(每次都能均匀划分数组):快速排序的平均时间复杂度为 O(nlogn)。在理想情况下,每次都能均匀地将数组划分为两半,递归树呈现完全二叉树形态,此时快速排序的最好时间复杂度为 O(nlogn)。
- 最坏情况(每次划分只将数组划分为一个元素和其余元素两部分):当输入数组已经是有序(或逆序)时,每次划分都将数组划分为一个元素和其余元素两部分,递归树呈现线性形态,此时快速排序的最坏时间复杂度为 O(n2)。
- 平均情况:在大多数实际应用中,快速排序的平均时间复杂度接近 O(nlogn)。
空间复杂度:快速排序的空间复杂度主要取决于递归调用的栈空间,最坏情况下需要 O(n) 的辅助空间,但在平均情况下为 O(logn)。
稳定性:快速排序不是稳定的排序算法,因为在分区过程中,相等的元素可能会因为相对位置的改变而改变排序后的顺序。
快速排序以其高效的平均时间复杂度和原地排序特性,在实践中被广泛应用于各种排序场景。以下是快速排序的Python实现:
1def quick_sort(arr):
2 if len(arr) <= 1: # 基础情况:数组长度为0或1时,已是有序
3 return arr
4
5 pivot = arr[len(arr) // 2] # 选择基准元素,这里选择中间元素
6 left = [x for x in arr if x < pivot] # 小于基准的元素
7 middle = [x for x in arr if x == pivot] # 等于基准的元素
8 right = [x for x in arr if x > pivot] # 大于基准的元素
9
10 # 递归对左右子序列进行快速排序,然后合并结果
11 return quick_sort(left) + middle + quick_sort(right)
通过递归对左右子序列进行快速排序,最终合并得到有序数组。在实际应用中,为了减少不必要的数据复制,可以采用in-place版本的快速排序,即在原数组上进行分区操作,而非创建新的子数组。