快速排序基本思想是:在数组找到一个数作为基准数,通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,基准数放在中间,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
排序算法 | 平均情况 | 最好情况 | 坏情况 | 稳定性 | 空间复杂度(辅助空间) |
快速排序 | O(nlogn) | O(nlogn) | O(n2) | 不稳定 | O(logn)~O(n) |
下面为经典快速排序排序(基准数位置固定):
import java.util.Arrays;
public class QuickSort {
public static void main(String[] args) {
int arr[]= {6,3,45,67,23,61,89,66,98,34,67,89,50};
int arr1[]= {6,3,45,67,23,61,89,66,98,34,67,89,50};
printArray(arr);
quickSort(arr);
printArray(arr);
Arrays.sort(arr1);
printArray(arr1);
}
//如果数组为null或者长度小于2则return
//否则进行快速排序
public static void quickSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
quickSort(arr, 0, arr.length - 1);
}
//经典快速排序
public static void quickSort(int[] arr, int l, int r) {
//当数组个数大于等于2时,需要做比较划分
if (l < r) {
//经典快速排序,就是默认和最后一个值进行比较
int[] p = partition(arr, l, r);
printArray(arr);
//对划分好的左右两边,进行随机快速排序
quickSort(arr, l, p[0] - 1);
quickSort(arr, p[1] + 1, r);
}
}
//首先划分小于区域和大于区域的范围,less为最小下标减一,more为最后元素下标
//和最后的一个数进行比较划分,比arr[r]小的,与小于区域的下一个数交换,小于区域扩大一个范围(+1),当前位置加一
//如果比arr[r]大,则和大于区域的下一个数交换,大于区域扩大一个范围(-1)
//如果相等,则当前位置加一
//当l>=more则退出循环,将more的位置和最后一个比较数交换
//此函数完成数组中最后一个数为中间点的左右划分
public static int[] partition(int[] arr, int l, int r) {
int less = l - 1;
int more = r;
while (l < more) {
if (arr[l] < arr[r]) {
swap(arr, ++less, l++);
} else if (arr[l] > arr[r]) {
swap(arr, --more, l);
} else {
l++;
}
}
swap(arr, more, r);
return new int[] { less + 1, more };
}
//交换
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
//打印数组
private static void printArray(int[] arr) {
if (arr == null) {
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
}
import java.util.Arrays;
public class Code_04_QuickSort {
//如果数组为null或者长度小于2则return
//否则进行快速排序
public static void quickSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
quickSort(arr, 0, arr.length - 1);
}
//随机快速排序
public static void quickSort(int[] arr, int l, int r) {
//当数组个数大于等于2时,需要做比较划分
if (l < r) {
//随机快速排序,随机选值,放置在最后进行比较
swap(arr, l + (int) (Math.random() * (r - l + 1)), r);
int[] p = partition(arr, l, r);
//对划分好的左右两边,进行随机快速排序
quickSort(arr, l, p[0] - 1);
quickSort(arr, p[1] + 1, r);
}
}
//首先划分小于区域和大于区域的范围,less为最小下标减一,more为最后元素下标
//和最后的一个数进行比较划分,比arr[r]小的,与小于区域的下一个数交换,小于区域扩大一个范围(+1),当前位置加一
//如果比arr[r]大,则和大于区域的下一个数交换,大于区域扩大一个范围(-1)
//如果相等,则当前位置加一
//当l>=more则退出循环,将more的位置和最后一个比较数交换
//此函数完成数组中某个随机数左右两边的划分
public static int[] partition(int[] arr, int l, int r) {
int less = l - 1;
int more = r;
while (l < more) {
if (arr[l] < arr[r]) {
swap(arr, ++less, l++);
} else if (arr[l] > arr[r]) {
swap(arr, --more, l);
} else {
l++;
}
}
swap(arr, more, r);
return new int[] { less + 1, more };
}
//交换
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
// for test
public static void comparator(int[] arr) {
Arrays.sort(arr);
}
// 产生一个长度为100以内,值为-100~100的随机数组
public static int[] generateRandomArray(int maxSize, int maxValue) {
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
}
return arr;
}
// 复制数组
public static int[] copyArray(int[] arr) {
if (arr == null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}
// 比较数组是否相等
public static boolean isEqual(int[] arr1, int[] arr2) {
if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
return false;
}
if (arr1 == null && arr2 == null) {
return true;
}
if (arr1.length != arr2.length) {
return false;
}
for (int i = 0; i < arr1.length; i++) {
if (arr1[i] != arr2[i]) {
return false;
}
}
return true;
}
// 打印数组
public static void printArray(int[] arr) {
if (arr == null) {
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
// for test
public static void main(String[] args) {
int testTime = 500000;
int maxSize = 100;
int maxValue = 100;
boolean succeed = true;
//测试快速排序的正确性
// for (int i = 0; i < testTime; i++) {
// int[] arr1 = generateRandomArray(maxSize, maxValue);
// int[] arr2 = copyArray(arr1);
// quickSort(arr1);
// comparator(arr2);
// if (!isEqual(arr1, arr2)) {
// succeed = false;
// printArray(arr1);
// printArray(arr2);
// break;
// }
// }
// System.out.println(succeed ? "Nice!" : "Fucking fucked!");
int[] arr = generateRandomArray(maxSize, maxValue);
printArray(arr);
quickSort(arr);
printArray(arr);
}
}