快速排序是对冒泡排序的一种改进,由C. A. R. Hoare在1960年提出。快速排序采用分治策略以减少排序过程中的比较次数,它的最好情况O(nlogn),最坏情况O(n^2),平均时间复杂度O(nlogn)。
算法思想:
一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
案例:
以第一个数16作为基准,对整个数组进行排序,把比16小的放在16的左边,把比16大的放在16的右边。具体做法是在待排序的数组区间的左右两边分别设置一个游标,一个游标(i)从左往右找到比16大的数的位置,另一个游标(j)从右往左找到比16小的数的位置。找到后把两个游标位置的数进行交换。然后继续寻找(蓝色为基准,红色为找到了符合要求的数的位置并进行交换):
当游标 i 大于游标 j 时这一趟排序结束,注意游标 j 不是一小于游标 i 就结束,而是继续找到比基数小的数或者遍历完待排序数组区间才结束:
到此,16的左边都比16小,16的右边都比16大,然后再对两个子区间继续排序直到所有数全部有序为止:
对16左边的左区间排序,以7作为基准:
对7的左区间排序,以6作为基准:
对7的右区间排序,以8作为基准:
到此,16的左区间全部排序完成,再对16的右区间进行排序,以20作为基准:
对20的左区间排序,以19作为基准:
对19的左区间排序,以18作为基准:
全部排序完成:
JAVA代码:
package sort;
import java.util.Arrays;
import java.util.Random;
public class 快速排序 {
public static void main(String[] args) {
int array[] = rand();
quickSort(array, 0, array.length - 1);
System.out.println(Arrays.toString(array));
}
public static void quickSort(int[] a, int p, int r) {
if (p < r) {
int q = Partition(a, p, r);
quickSort(a, p, q - 1);// 对左半段排序
quickSort(a, q + 1, r);// 对右半段排序
}
}
public static int Partition(int[] a, int p, int r) {
int x = a[p];
int i = p;
int j = r + 1;
// 将小于x的交换到左边区域,将大于x的交换到右边区域
while (true) {
while (a[++i] < x && i < r)
;
while (a[--j] > x)
;
if (i >= j) {
break;
}
Swap(i, j, a);
}
a[p] = a[j];
a[j] = x;
return j;
}
public static void Swap(int a, int b, int list[]) {
int temp = list[a];
list[a] = list[b];
list[b] = temp;
}
public static int[] rand() {
int n = new Random().nextInt(1) + 15;
System.out.println("数组长度:" + n);
int a[] = new int[n];
for (int i = 0; i < n; i++) {
a[i] = new Random().nextInt(100) + 1;
}
System.out.println(Arrays.toString(a));
return a;
}
}