快速排序(Quick Sort)是一种高效的排序算法,由英国计算机科学家C.A.R. Hoare在1960年提出。它的基本思想是通过一次排序将待排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据都要小,然后再按这种方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序主要包括以下步骤:
- 选择一个基准元素(pivot)。
- 通过一趟排序将待排序记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分继续进行排序,以达到整个序列有序。
- 递归地对子序列进行快速排序。
下面是快速排序的 Java 实现以及详细的代码解析:
public class QuickSort {
// 快速排序的入口函数
public static void quickSort(int[] arr) {
if (arr == null || arr.length < 2) {
return; // 如果数组为空或只有一个元素,则不需要排序
}
quickSort(arr, 0, arr.length - 1); // 调用递归排序函数
}
// 递归排序函数
private static void quickSort(int[] arr, int left, int right) {
if (left < right) {
// 划分,获取pivot的索引
int pivotIndex = partition(arr, left, right);
// 递归排序左边
quickSort(arr, left, pivotIndex - 1);
// 递归排序右边
quickSort(arr, pivotIndex + 1, right);
}
}
// 划分函数
private static int partition(int[] arr, int left, int right) {
// 选择最右边的元素作为基准
int pivot = arr[right];
int i = left;
for (int j = left; j < right; j++) {
// 如果当前元素小于或等于pivot
if (arr[j] <= pivot) {
// 交换arr[i]和arr[j]
swap(arr, i, j);
// 将i右移
i++;
}
}
// 交换arr[i]和arr[right](即基准值)
swap(arr, i, right);
// 返回pivot的索引
return i;
}
// 交换数组中两个元素的位置
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {
int[] arr = {5, 3, 8, 4, 2};
quickSort(arr);
for (int num : arr) {
System.out.print(num + " ");
}
}
}
代码解析:
quickSort(int[] arr)
方法是快速排序的入口点,它首先检查数组是否为空或只有一个元素,如果是,则直接返回。然后调用递归排序函数quickSort(int[] arr, int left, int right)
。quickSort(int[] arr, int left, int right)
是一个递归方法,用于分解数组。它首先调用partition
方法将数组分成两部分,并返回基准元素(pivot)的索引。然后,递归地对基准元素左边和右边的子数组进行排序。partition(int[] arr, int left, int right)
方法负责划分数组。它选择一个基准元素(在这个实现中,我们选择最右边的元素作为基准),然后遍历数组,将所有小于或等于基准的元素移动到基准的左边,所有大于基准的元素移动到基准的右边。最后,将基准元素放到正确的位置,并返回其索引。swap(int[] arr, int i, int j)
方法是一个辅助方法,用于交换数组中两个元素的位置。main
方法中创建了一个待排序的数组,并调用quickSort
方法进行排序。排序完成后,遍历数组并打印排序结果。
快速排序的平均时间复杂度为 O(n log n),但在最坏情况下(例如当输入数组已经有序时),其时间复杂度会退化到 O(n^2)。为了优化最坏情况的表现,可以随机选择基准,或者使用三数取中法等方法来选择基准。此外,在实际应用中,快速排序也会结合插入排序等算法来优化小数组的处理效率。