摘要
快速排序(QuickSort)是一种高效的分治算法,由 Tony Hoare 于 1960 年发明。本文将介绍快速排序的基本原理、在 C++ 中的实现、性能分析以及实际示例。
引言
快速排序概述
快速排序是一种原地排序算法,平均时间复杂度为 O(n log n),最坏情况下为 O(n²)。它通过选择一个“枢轴”(pivot)将数组分为两部分:小于枢轴的元素和大于枢轴的元素,然后递归排序子数组。
适用场景
适合大数据集的内部排序。
与其他排序算法(如归并排序)比较,空间复杂度更低(O(log n) 递归深度)。
文章结构
算法原理
C++ 实现
示例与测试
复杂度分析
结论
算法原理
分治思想
快速排序的核心是“分治”:
选择枢轴(pivot),通常取数组第一个、最后一个或随机元素。
分区(Partition):将数组重排,使小于 pivot 的元素在左,大于的在右。
递归:对左右子数组重复步骤 1-2。
分区过程
假设数组 A[low…high],pivot = A[high]:
i = low - 1
对于 j 从 low 到 high-1:
如果 A[j] <= pivot,交换 A[++i] 和 A[j]
交换 A[i+1] 和 A[high],返回 i+1 作为分区点。
伪代码:
1 2 3 4 5 procedure quicksort (A, low, high) if low < high then pivot_index := partition(A, low, high) quicksort(A, low, pivot_index - 1 ) quicksort(A, pivot_index + 1 , high)
C++ 实现
定义函数
partition 函数用于将给定数组分为两组,小于最后一个元素值的放到左边,大于最后一个元素值的放到右边。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 int partition (std::vector<int >& arr, int low, int high) { int pivot = arr[high]; int i = low - 1 ; for (int j = low; j < high; ++j) { if (arr[j] <= pivot) { ++i; std::swap (arr[i], arr[j]); } } std::swap (arr[i + 1 ], arr[high]); return i + 1 ; }
quicksort 函数用于递归地对左右两边的数组进行排序。
1 2 3 4 5 6 7 8 void quicksort (std::vector<int >& arr, int low, int high) { if (low < high) { int pi = partition (arr, low, high); quicksort (arr, low, pi - 1 ); quicksort (arr, pi + 1 , high); } }
quick_sort 函数就是一个接口函数,简化形参。
1 2 3 4 void quick_sort (std::vector<int >& arr) { quicksort (arr, 0 , arr.size () - 1 ); }
完整代码
所需头文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #include <iostream> #include <vector> #include <algorithm> using namespace std;#include <iostream> #include <vector> #include <algorithm> using namespace std;int partition (std::vector<int >& arr, int low, int high) { int pivot = arr[high]; int i = low - 1 ; for (int j = low; j < high; ++j) { if (arr[j] <= pivot) { ++i; std::swap (arr[i], arr[j]); } } std::swap (arr[i + 1 ], arr[high]); return i + 1 ; } void quicksort (std::vector<int >& arr, int low, int high) { if (low < high) { int pi = partition (arr, low, high); quicksort (arr, low, pi - 1 ); quicksort (arr, pi + 1 , high); } } void quick_sort (std::vector<int >& arr) { quicksort (arr, 0 , arr.size () - 1 ); } int main () { std::vector<int > arr = {10 , 7 , 8 , 9 , 1 , 5 }; std::cout << "原始数组: " ; for (int num : arr) std::cout << num << " " ; std::cout << std::endl; quick_sort (arr); std::cout << "排序后: " ; for (int num : arr) std::cout << num << " " ; std::cout << std::endl; return 0 ; }
原始数组: 10 7 8 9 1 5
排序后: 1 5 7 8 9 10
代码说明
实用 std::vector 作为动态数组。
partition 函数实现 Lomuto 分区方案(高效,原地)。
递归深度平均 log n,避免栈溢出(对于 n < 10^6 安全)。
简单示例
原始:10 7 8 9 1 5
排序:1 5 7 8 9 10
边界测试
空数组:无操作。
已排序数组:O(n^2)最坏,但随即 privot 可优化。
逆序数组:类似。