快速排序 (Quick Sort)
快速排序是一种高效的排序算法,采用分治法策略来把一个序列分为较小和较大的两个子序列,然后递归地排序两个子序列。
算法原理
快速排序使用分治法(Divide and conquer)策略来把一个序列分为较小和较大的两个子序列,然后递归地排序两个子序列。基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
时间复杂度
O(n log n)
空间复杂度
O(log n)
稳定性
不稳定
算法步骤
- 从数列中挑出一个元素,称为"基准"(pivot)
- 重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任何一边)
- 递归地把小于基准值元素的子数列和大于基准值元素的子数列排序
代码实现
public class QuickSort {
public static void quickSort(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);
}
}
// 分区函数
private static int partition(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++;
// 交换元素
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// 交换基准元素到正确位置
int temp = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp;
return i + 1;
}
// 测试方法
public static void main(String[] args) {
int[] arr = {64, 34, 25, 12, 22, 11, 90};
System.out.println("排序前:");
printArray(arr);
quickSort(arr, 0, arr.length - 1);
System.out.println("排序后:");
printArray(arr);
}
static void printArray(int[] arr) {
for (int value : arr) {
System.out.print(value + " ");
}
System.out.println();
}
}
应用场景
- 大规模数据排序:在实际应用中,快速排序通常比其他O(n log n)算法更快
- 系统排序:许多编程语言的标准库中使用快速排序或其变种作为排序算法
- 内存受限环境:原地排序特性使其适用于内存受限的环境
优缺点
优点
- 原地排序,空间复杂度低
- 平均时间复杂度为O(n log n),效率高
- 实际应用中通常比其他O(n log n)算法更快
- 实现相对简单
缺点
- 不稳定排序算法
- 最坏情况时间复杂度为O(n²)
- 递归实现可能导致栈溢出