1. 快速排序的本质与核心思想
快速排序(Quick Sort)是计算机科学领域最经典的算法之一,由英国计算机科学家托尼·霍尔(Tony Hoare)在1959年发明。这个算法之所以被称为"快速",是因为它在实际应用中几乎总是比其他O(n log n)算法更快,尽管它的最坏时间复杂度是O(n²)。
快速排序的核心思想是分治法(Divide and Conquer),它将一个大问题分解为若干个小问题来解决。具体来说,快速排序通过以下三个步骤工作:
- 选择一个基准元素(pivot)
- 将数组分为两部分:小于基准的元素和大于基准的元素
- 递归地对这两部分进行排序
这种分而治之的策略使得快速排序在处理大规模数据时特别高效。与归并排序不同,快速排序是原地排序算法,只需要O(log n)的额外空间(用于递归栈),这使得它在内存受限的环境中特别有用。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 快速排序的工作原理详解
2.1 分区过程解析
分区(Partition)是快速排序的核心操作。让我们用一个具体例子来理解这个过程:
假设我们有数组:[3, 6, 8, 10, 1, 2, 1]
选择最后一个元素1作为基准(pivot)。分区过程如下:
- 初始化两个指针:i(指向小于基准的元素的末尾)和j(遍历数组)
- 当j遇到小于基准的元素时,i增加1,然后交换i和j位置的元素
- 最后,将基准元素放到i+1的位置
经过分区后,数组变为:[1, 1, 2, 10, 6, 8, 3]
此时,基准元素1位于正确的位置,所有小于1的元素在其左侧,大于1的元素在其右侧。
2.2 递归排序过程
分区完成后,我们递归地对左右两部分进行同样的操作:
- 左侧子数组:[1](已经有序)
- 右侧子数组:[2, 10, 6, 8, 3]
对右侧子数组再次进行快速排序:
- 选择最后一个元素3作为基准
- 分区后得到:[2, 3, 6, 8, 10]
- 基准元素3位于正确位置
继续递归:
- 左侧:[2](有序)
- 右侧:[6, 8, 10]
最终,整个数组变为有序:[1, 1, 2, 3, 6, 8, 10]
3. 快速排序的实现细节
3.1 Python实现解析
让我们看一个Python实现的快速排序:
python复制def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[-1] # 选择最后一个元素作为基准
left = [x for x in arr[:-1] if x <= pivot]
right = [x for x in arr[:-1] if x > pivot]
return quick_sort(left) + [pivot] + quick_sort(right)
这个实现虽然简洁,但有几个问题:
- 每次递归都创建新列表,空间复杂度高
- 总是选择最后一个元素作为基准,可能导致最坏情况
3.2 优化版本实现
更高效的原地排序版本:
python复制def quick_sort_inplace(arr, low=0, high=None):
if high is None:
high = len(arr) - 1
if low < high:
pi = partition(arr, low, high)
quick_sort_inplace(arr, low, pi - 1)
quick_sort_inplace(arr, pi + 1, high)
def partition(arr, low, high):
pivot = arr[high]
i = low
for j in range(low, high):
if arr[j] < pivot:
arr[i], arr[j] = arr[j], arr[i]
i += 1
arr[i], arr[high] = arr[high], arr[i]
return i
这个版本:
- 原地排序
