快速排序是分而治之思想在排序算法上的应用,是处理大数据最快的排序算法之一。快速排序的最坏运行情况是O(n),比如顺序数列。但他的平均期望时间是O(nlogn),在处理顺序性弱的数列时速度很快。
java实现
public void quickSort() {
Integer[] arr = new Integer[]{43, 77, 29, 39, 66, 83, 104, 93, 11, 10, 18, 27};
quickSort(arr, 0, arr.length - 1);
for (Integer integer : arr) {
System.out.println(integer + "");
}
}
public void quickSort(Integer[] arr, int left, int right) {
if (left < right) {
// 计算基准值的正确位置,同时移动数组,达到基准值左边是比基准值小的元素,基准值右边是比基准值大的元素
// 每一次执行partition,都会计算并移动基准值的最终正确位置
int partitionIndex = partition(arr, left, right);
// 递归基准值左边的序列,计算左边序列的基准值的正确位置并移动
quickSort(arr, left, partitionIndex);
// 递归基准值右边边的序列,计算下右边序列基准值的正确位置并移动
quickSort(arr, partitionIndex + 1, right);
}
}
/**
* 计算数组arr从left到right位置的序列中基准值的正确位置,并移动,
* 达到 基准值左边都是小于基准值的元素,基准值右边都是大于基准值的元素
* @param arr 数组
* @param left 数组中待排序序列,起始位置
* @param right 数组中待排序序列,结束位置
* @return 基准值排序完成后的正确位置
*/
public int partition(Integer[] arr, int left, int right) {
// 将待排序序列最左边的元素当做基准
int pivot = left;
// 从基准后边1个位置的元素开始与基准元素对比,即left+1
int index = pivot + 1;
// 数组中从left到right位置,共有right-left+1个元素,因为从left+1个元素开始对比,所以需要对比right-left次
for (int i = index; i <= right; i++) {
if (arr[i] < arr[pivot]) {
// 把比基准元素小的值,与基准值后边1个位置left+1的元素对换位置
swap(arr, i, index);
// 记录比基准值小的元素的数量
index++;
}
}
// 总共比基准值小的元素数量是index,由此推断出基准值在完成全部排序后的位置是index,把基准值元素放到正确的位置上
swap(arr, pivot, index - 1);
//此时,arr数组中left到right的序列,index-1左边是比基准值小的元素,index-1右边是比基准值大的元素
return index - 1;
}
/**
* 交换数组arr中第i个和第j个元素的位置
*/
public void swap(Integer[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
输出结果: 10 11 18 27 29 39 43 66 77 83 93 104
算法步骤
- 从数列中条一个元素,作为基准值(Pivot)
- 对数列进行排序,计算并移动基准值到正确位置,使基准值左边都是小于基准值的元素,右边都是大于基准值的元素。这个操作称为分区。即partition方法的实现逻辑
- 递归地对大于、小于基准值的两个分区执行步骤2的操作,最终完成排序。即quickSort方法的实现逻辑