快速排序由于排序效率在同为O(nlogn)的几种排序方法中效率较高,因此经常被采用,再加上快速排序使用了分治法的思想,算是基础排序中比较高档的一种排序了。
1.先从数列中取出一个数作为基准数,可以是第一个,也可是中间的或者最后的,但是第一步要把这个基准数与数组最后一位对换。
2.将比这个数大(小)的数全放到它的右边,小于或等于(大于或等于)它的数全放到它的左边。
3.对左右区间重复第二步,直到各区间只有一个数(递归定义)。
public class Quick {
public static void main(String[] args) {
Integer arrA[] = new Integer[] { 13, 1, 2, 43, 65, 23, 76, 77, 23, 11, 99 };
Integer arrB[] = new Integer[] { 13, 1, 2, 43, 65, 23, 76, 77, 23, 11, 99 };
Integer[] arr1 = quickSortBig2Small(arrA, 0, arrA.length - 1);
System.out.println("从大到小:" + Arrays.toString(arr1));
Integer[] arr2 = quickSortSmall2Big(arrB, 0, arrB.length - 1);
System.out.println("从小到大:" + Arrays.toString(arr2));
}
/**
* 快排从大到小
*/
private static Integer[] quickSortBig2Small(Integer[] arr, int low, int high) {
// 如果开始点和结束点没有重叠的时候,也就是指针没有执行到结尾
if (low < high) {
// 重新获取中间点
int mid = getIndexFromBig2Small(arr, low, high);
quickSortBig2Small(arr, low, mid - 1);
quickSortBig2Small(arr, mid + 1, high);
}
return arr;
}
/**
* 快排从小到大
*/
private static Integer[] quickSortSmall2Big(Integer[] arr, int low, int high) {
// 如果开始点和结束点没有重叠的时候,也就是指针没有执行到结尾
if (low < high) {
// 重新获取中间点
int mid = getIndexFromSmall2Big(arr, low, high);
quickSortSmall2Big(arr, low, mid - 1);
quickSortSmall2Big(arr, mid + 1, high);
}
return arr;
}
/**
* 交换数组元素
*/
private static void swap(Integer[] arr, int low, int high) {
int temp = arr[low];
arr[low] = arr[high];
arr[high] = temp;
}
/**
* 获取中间值(从大到小)
*/
private static int getIndexFromBig2Small(Integer[] arr, int low, int high) {
// 中值作为中点
int index = (low + high) / 2;
int midNum = arr[index];
// 无论取的值是哪一个,都应该将其放在最后面
swap(arr, index, high);
while (low < high) {
// 左侧值大于或者等于右侧值时候,只需要移动指针即可,不需要交换( 注意 =,没有会陷入死循环)
while (low < high && arr[low] >= midNum)
low++;
swap(arr, low, high);
// 右侧值小于或者等于右侧值时候,只需要移动指针即可,不需要交换
while (low < high && arr[high] <= midNum)
high--;
swap(arr, low, high);
}
return high;
}
/**
* 获取中间值(从小到大)
*/
private static int getIndexFromSmall2Big(Integer[] arr, int low, int high) {
// 中值作为中点
int index = (low + high) / 2;
int midNum = arr[index];
// 无论取的值是哪一个,都应该将其放在最后面
swap(arr, index, high);
while (low < high) {
// 左侧值小于或者等于右侧值时候,只需要移动指针即可,不需要交换( 注意 =,没有会陷入死循环)
while (low < high && arr[low] <= midNum)
low++;
swap(arr, low, high);
// 右侧值小大于于或者等于右侧值时候,只需要移动指针即可,不需要交换
while (low < high && arr[high] >= midNum)
high--;
swap(arr, low, high);
}
return high;
}
}