快速排序
package case99_QuickSort;
public class QuickSort {
// 快速排序
public static void main(String[] args) {
int[] arr = { 9, 9, 5, 8, 3, 7, 4, 6, 2 };
QSort(arr);
for (int i = 0; i < arr.length; i++)
System.out.print(arr[i] + " ");
}
// 快排
public static void QSort(int[] arr) {
if (arr == null)
return;
if (arr.length == 0)
return;
// 快排
QS(arr, 0, arr.length - 1);
}
// 递归方式完成快排
public static void QS(int[] arr, int low, int high) {
//优化2:当数组数量较小时使用插入排序,经验值7个或者50个以下
if (low < high) {
// 把中枢值放到合理的位置,并且得到中枢值得位置
int pivotPos = partition(arr, low, high);
// 中枢值位置左侧进行递归
QS(arr, low, pivotPos - 1);
// 中枢值位置右侧进行递归
QS(arr, pivotPos + 1, high); //优化3:尾递归。因为采用了迭代,减小了栈的深度。
}
}
// 获得中枢的位置
public static int partition(int[] arr, int low, int high) {
// 取第一个数作为中枢值 (优化1:这里可以采用三数取中优化)
int pivotKey = arr[low];
// 从两头开始向中间取值
while (low < high) {
// 从最右侧的值开始比较
while (low < high && pivotKey <= arr[high])
high--;
arr[low] = arr[high];
// 从最左侧的值开始比较
while (low < high && pivotKey >= arr[low])
low++;
arr[high] = arr[low];
}
arr[low] = pivotKey;
return low;
}
}
快速排序优化版本
package case99_QuickSort;
public class QuickSortOpt {
/**
* 对快排进行优化 优化1:三数取中优化 优化2:优化小数组时的排序方案 优化3:优化递归
*
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = { 9, 9, 5, 8, 3, 7, 4, 6, 2 };
Qsort(arr);
for (int i = 0; i < arr.length; i++)
System.out.print(arr[i] + " ");
}
// 排序
public static void Qsort(int[] arr) {
if (arr == null)
return;
if (arr.length == 0)
return;
// 快速排序
QS(arr, 0, arr.length - 1);
}
// 采用递归的方式完成排序
public static void QS(int[] arr, int low, int high) {
// 优化2:数组个数大于一定个数的时候,采用快速排序;否则,采用直接插入排序。
int Distance = high - low;
if (Distance > 7) {
while (low < high) { // 优化3:优化递归操作
// 获取中枢值的位置,并且完成大小数组的划分
int pivotPos = partition(arr, low, high);
QS(arr, low, pivotPos - 1);
low = pivotPos + 1; // 优化3:采用迭代的方法,可以缩减栈的深度。
}
} else
// 直接插入排序
InsertSort(arr, low, high);
}
// 直接插入
public static void InsertSort(int[] arr, int low, int high) {
if (low < high) {
for (int i = low; i < high; i++) {
if (arr[low + 1] < arr[low]) {
int temp = arr[low + 1];
// 记录后移
int j;
for (j = low + 1; temp < arr[j]; j--) {
arr[j] = arr[j - 1];
}
arr[j] = temp;
}
}
}
}
// 获取中枢值的位置,并且完成大小数组的划分
public static int partition(int[] arr, int low, int high) {
// 优化1:三数取中
int m = low + (high - low) / 2;
if (arr[m] > arr[high]) // 小的数放到low的位置
swap(arr, m, high);
if (arr[low] > arr[high])
swap(arr, low, high);
if (arr[low] > arr[m])
swap(arr, low, m);
int pivotKey = arr[low];
// 从两头向中间开始交替靠近
while (low < high) {
while (low < high && arr[high] >= pivotKey)
high--;
arr[low] = arr[high];
while (low < high && arr[low] <= pivotKey)
low++;
arr[high] = arr[low];
}
arr[low] = pivotKey;
return low;
}
// 完成low,high位置两个数的交换
public static void swap(int[] arr, int low, int high) {
int temp;
if (arr[low] > arr[high]) {
temp = arr[low];
arr[low] = arr[high];
arr[high] = temp;
}
}
}