快速排序(Quick Sort)是一种高效的排序算法,采用了分治(Divide and Conquer)的策略。以下为你详细介绍:
1. 基本原理
- 从待排序的数据集中选择一个元素作为基准值(pivot)。基准值的选择方法多样,常见的有选择第一个元素、最后一个元素或者中间元素等。
- 重新排列数据集,将所有小于基准值的元素放在基准值的左边,所有大于基准值的元素放在基准值的右边。这个过程称为分区(partition)操作。经过分区后,基准值就处于它在最终排序数组中的正确位置。
- 对基准值左边和右边的两个子数据集,分别递归地应用上述步骤,直到每个子数据集只有一个元素(或没有元素),此时整个数据集就已完全排序。
2. 算法步骤
- 选择基准值:从数组中选择一个元素作为基准值。例如,可以选择数组的第一个元素、最后一个元素或者中间元素。
- 分区操作:
- 初始化两个指针,一个指向数组起始位置(left),另一个指向数组末尾位置(right)。
- 从右向左移动
right
指针,找到第一个小于基准值的元素;从左向右移动left
指针,找到第一个大于基准值的元素。 - 如果
left
指针小于right
指针,交换这两个元素,然后继续移动指针寻找下一对需要交换的元素。 - 当
left
指针和right
指针相遇时,将基准值与left
指针(或right
指针,此时两者位置相同)指向的元素交换。此时,基准值处于正确的排序位置,并且数组被分成了左右两个子数组,左边子数组的所有元素小于基准值,右边子数组的所有元素大于基准值。
- 递归排序子数组:对左右两个子数组分别重复上述选择基准值和分区的过程,直到子数组的长度为 1 或 0,此时整个数组完成排序。
3. 代码实现
以下是Python语言实现快速排序的代码:
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[0]
left = []
right = []
for num in arr[1:]:
if num <= pivot:
left.append(num)
else:
right.append(num)
return quick_sort(left) + [pivot] + quick_sort(right)
4. 算法分析
- 时间复杂度:
- 平均情况:快速排序的平均时间复杂度为 \(O(nlogn)\),其中
n
是待排序数组的元素个数。这是因为每次分区操作大致将数组分成两个长度接近的子数组,递归深度为 \(logn\),每层递归的操作次数为n
。 - 最坏情况:当每次选择的基准值都是数组中的最大或最小元素时,分区操作会使数组极度不平衡,一个子数组为空,另一个子数组长度为
n - 1
。这种情况下,快速排序的时间复杂度退化为 \(O(n^2)\)。
- 平均情况:快速排序的平均时间复杂度为 \(O(nlogn)\),其中
- 空间复杂度:
- 平均情况:空间复杂度主要取决于递归调用的深度,平均递归深度为 \(logn\),所以平均空间复杂度为 \(O(logn)\)。
- 最坏情况:在最坏情况下,递归深度达到
n
,空间复杂度为 \(O(n)\)。
- 稳定性:快速排序是不稳定的排序算法。例如,在数组
[2, 2*, 1]
中,如果选择第一个2
作为基准值,在分区过程中,第二个2
可能会被移动到第一个2
的前面,导致相等元素的相对顺序发生改变。