1 package test;
2
3 /*
4 * 快速排序 在最坏情况下是O(N^2),平均的时间复杂度是O(N*logN) 不稳定
5 * 算法稳定性 -- 假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;
6 * 并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的!
7 * 快速排序采用的思想是分治思想。
8 * 快速排序是找出一个元素(理论上可以随便找一个)作为
9 * 基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,
10 * 基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置。
11 * 递归快速排序,将其他n-1个元素也调整到排序后的正确位置。最后每个元素都是在
12 * 排序后的正确位置,排序完成。所以快速排序算法的核心算法是分区操作,
13 * 即如何调整基准的位置以及调整返回基准的最终位置以便分治递归。
14 */
15 public class QuickSort {
16 public static void sort(int[] a) {
17 sort(a,0,a.length-1);
18 }
19 private static void sort(int[] a,int low,int high) {
20 if(low >= high) {
21 return;
22 }
23 int j = partition(a,low,high);
24 sort(a,low,j-1);
25 sort(a,j+1,high);
26 }
27 //寻找切分元素索引
28 private static int partition(int[] a,int low,int high) {
29 int i = low;
30 int j = high + 1;
31 //取a[low]为基准元素
32 int temp = a[low];
33 while(true) {
34 //i的左边不大于切分元素
35 while(a[++i]<temp) {
36 //注意索引是否越界
37 if(i == high)
38 break;
39 }
40 //j的右边不小于切分元素
41 while(a[--j]>temp) {}
42 //当i与j相遇时,遍历完low和high之间的元素,
43 //a[i]>=temp,a[j]<=temp;此时退出
44 if(i>=j)
45 break;
46 //当i<j时,未遍历完low和high之间的元素,
47 //a[i]>=temp,a[j]<=temp;此时交换
48 swap(a,i,j);
49 }
50 //将切分元素放在正确位置
51 swap(a,low,j);
52 return j;
53 }
54 private static void swap(int[] a,int i,int j) {
55 int temp = a[i];
56 a[i] = a[j];
57 a[j] = temp;
58 }
59 public static void main(String[] args) {
60 int[] a = new int[100];
61 for(int i=0;i<a.length;i++) {
62 a[i] = (int)(Math.random()*100);
63 }
64 sort(a);
65 int n = 0;
66 for(int i:a) {
67 System.out.print(i+" ");
68 n++;
69 if(n==20) {
70 n = 0;
71 System.out.println();
72 }
73
74 }
75 }
76 }