快速排序( Quick Sort )
交换类排序,是对冒泡排序的升级
排序的分类
基本思想:
通过一趟排序将待排记录分割正独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。
图解
思路
1.定义四个方法
- 主方法
- 递归方法
- 排序方法
- 交换方法
2.递归排序低子表和高子表
3.枢轴 pivot 的选择
代码
import java.util.Arrays;
public class Quick_Sort {
public static void main(String[] args) {
int[] arr = {50, 10, 40, 30, 50, 70, 80, 60, 90};
QSort(arr, 0, arr.length-1);
System.out.println(Arrays.toString(arr));
}
public static void QSort(int[] arr,int low,int high){
int pivot;
if (low < high) {
pivot = Partition(arr, low, high);//将数组一分为二
QSort(arr, low, pivot - 1);//对低子表进行递归
QSort(arr, pivot + 1, high);//对高子表进行递归
}
}
public static int Partition(int[] arr,int low,int high) {
int pivotkey;
pivotkey = arr[low];
while (low < high) {
while (low < high && arr[high] >= pivotkey) {
high--;
}
swap(arr, low, high);
while (low < high && arr[low] <= pivotkey) {
low++;
}
swap(arr, low, high);
}
return low;
}
public static void swap(int[] arr, int low, int high) {
int temp = arr[low];
arr[low] = arr[high];
arr[high] = temp;
}
}
代码优化
1、优化选取枢轴
三数取中(median-of-three)法:取三个关键字进行排序,将中间数作为枢轴,一般是取左端、中间和右端三个数。
int pivotkey;
int m = low + (high - low) / 2;
if (arr[low] > arr[high])
swap(arr, low, high);//保证左端较小
if (arr[m] > arr[high])
swap(arr,high,m);//保证中间较小
if (arr[m] > arr[low])
swap(arr, m, low);//保证左端较小
pivotkey = arr[low];
2、优化不必要的交换
public static int Partition(int[] arr,int low,int high) {
int pivotkey;
//省略优化一中的 三数取中的代码
pivotkey = arr[low];
int temp = pivotkey;//将枢轴关键字备份到 temp
while (low < high) {
while (low < high && arr[high] >= pivotkey) {
high--;
}
arr[low] = arr[high];//采用替换而不是交换方式
// swap(arr, low, high);
while (low < high && arr[low] <= pivotkey) {
low++;
}
arr[high] = arr[low];//采用替换而不是交换方式
// swap(arr, low, high);
}
arr[low] = temp;
return low;
}
3、优化小数组时的排序方案
public static void QSort(int[] arr,int low,int high){
int max_sort = 7;
int pivot;
//数组长度大于7才用快速排序
if ((low - high) > max_sort) {
pivot = Partition(arr, low, high);//将数组一分为二
QSort(arr, low, pivot - 1);//对低子表进行递归
QSort(arr, pivot + 1, high);//对高子表进行递归
}
//数组长度小于7时,用直接插入排序
else {
InsertSort(arr);//直接插入排序
}
}
4、优化递归操作
public static void QSort(int[] arr,int low,int high){
int max_sort = 7;
int pivot;
if ((low - high) > max_sort) {
while(low<high){
pivot = Partition(arr, low, high);//将数组一分为二
QSort(arr, low, pivot - 1);//对低子表进行递归
low = pivot + 1;
}
//QSort(arr, pivot + 1, high);//对高子表进行递归
} else {
InsertSort(arr);
}
}