1 实现原理和步骤
快速排序算法的时间复杂度为0(n * log2n),本质上是通过将一个数组划分为两个子数组,然后递归调用自身为每一个子数组进行快速排序来实现的。核心步骤主要有2点:第1点是数组的划分
把数组或子数组划分成比arr[调整后基准数的位置]小的元素在左边,大的在右边;
第2点是递归调用
1)调用自身对左边的一组进行排序;2)调用自身对右边的一组进行排序。
2 完整代码
public class QuickSort {
/**
* 统计调用partition(int arr[], int l, int r)函数的次数
*/
static int count = 0;
/**
* 快速排序
* 通过将一个数组划分成2个子数组,然后通过递归调用自身为每一个子数组进行快速排序。
* @param arr
* @param l
* @param r
*/
public static void quickSort(int arr[], int l, int r){
if(l < r){
int i = partition(arr, l, r);
quickSort(arr, l, i - 1); // 递归调用
quickSort(arr, i + 1, r);
}
}
/**
* 划分数组
* 比arr[调整后基准数的位置]小的元素在左边,大的在右边
* @param arr
* @param l
* @param r
* @return
*/
public static int partition(int arr[], int l, int r) {
int i = l, j = r;
int temp = arr[l]; // 设置基准数
while (i < j) {
// 先从右先前查找小于temp的数来填充arr[i]
while (i < j && arr[j] >= temp) {
j--;
}
// 将arr[j]赋值到arr[i]中
if (i < j) {
arr[i] = arr[j];
i++; // 该位置已经被填充,需要向右移动
}
// 再从左向右查找大于或等于temp的数来填充arr[j]
while (i < j && arr[i] < temp) {
i++;
}
// 将arr[i]赋值到arr[j]中
if (i < j) {
arr[j] = arr[i];
j--; // 该位置已经被填充,需要向左移动
}
}
arr[i] = temp; // 当i = j时,退出循环,即调整后的基准数位置=i=j,将temp赋值给arr[i]
// 打印调用过程
System.out.println("第" + ++count + "次调用的基准数位置: " + i);
System.out.println("第" + count + "次调用的结果: " + Arrays.toString(arr));
System.out.println(); //换行
return i;
}
/**
* 测试
* @param args
*/
public static void main(String[] args) {
// 初始化数组
int[] arr = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
// 快速排序
quickSort(arr, 0, arr.length - 1);
}
}
3 测试结果
4 参考文献
[1] Robert, Lafore., Java数据结构和算法.第2版 版. 2004: 中国电力出版社.[2] Sedgewick Robert与Wayne Kevin., 算法. 2012: 人民邮电出版社.