快速排序
快速排序:分而治之的威力
排序是算法世界的基石,而快速排序无疑是其中最闪耀的明星之一。它由Tony Hoare于1960年发明,以其优雅的“分治”思想和平均情况下极高的效率,成为实践中最常用的排序算法。
快速排序的基本思想
快排的核心可以概括为三步:
- 挑基准:从数组中选一个元素作为“基准”。
- 分区:重新排列数组,所有比基准小的放在其左边,比基准大的放在右边(操作结束后,基准就位于其最终排序后的正确位置)。
- 递归:递归地对基准左右两边的子数组进行快速排序。
为什么需要快速排序?
虽然其最坏情况(如数组已有序)时间复杂度是 O(n²),但其平均复杂度为 O(n log n),且常数因子很小,在实际应用中通常比其他 O(n log n) 算法(如归并排序)更快。此外,它是原地排序,空间复杂度为 O(log n)(递归栈),在内存使用上也很有优势。
灵魂所在:分区操作
分区是快排的灵魂。Lomuto分区方案或Hoare原始分区方案都旨在高效地完成重排。
// Lomuto分区方案(易于理解)
int partition(vector<int>& arr, int low, int high) {
int pivot = arr[high]; // 选择最后一个元素作为基准
int i = low; // i指向小于基准区域的末尾
for (int j = low; j < high; j++) {
if (arr[j] <= pivot) { // 当前元素小于等于基准
swap(arr[i], arr[j]);
i++; // 小于基准的区域扩大了
}
}
swap(arr[i], arr[high]); // 将基准放到正确位置
return i; // 返回基准的索引
}
快速排序的应用场景
作为高效的通用排序算法,它被广泛集成在各种编程语言的标准库中(如C++的qsort,Java的Arrays.sort)。在处理大数据集、需要内存效率的场合,快排是首选。其“分治”思想也启发了众多其他算法,如快速选择算法(用于在未排序数组中寻找第K大的元素)。
总结
快速排序完美诠释了“分而治之”的威力:通过一个简单的分区操作,将一个大问题分解为两个独立的子问题。
浙公网安备 33010602011771号