// 随机找一个数和最后一个数做交换,然后做划分值。划分出来的位置变了概率事件。 O(N*logN) public static void QuickSort(int[] arr) { if (arr == null || arr.length < 2) { return; } Process(arr, 0, arr.length - 1); } public static void Process(int[] arr, int L, int R) { if (L >= R) { return; } // L~R随机选取 Swap(arr, L + (int) (Math.random() * (R - L + 1)), R); int[] equalArea = netherlandsFlag(arr, L, R); // 划分等于区域的左边界,右边界 Process(arr, L, equalArea[0] - 1);// <区 Process(arr, equalArea[1] + 1, R);// >区 } public static int[] netherlandsFlag(int[] arr, int L, int R) { if (L > R) { // L...R L>R return new int[] { -1,-1 }; } if (L == R) { return new int[] { L,R }; } int less = L - 1; // < 区 左边界 int more = R; // > 区 右边界 int index = L; while (index < more) { // 当前位置index和 >区的边界撞上停止 if (arr[index] == arr[R]) { index++; } else if (arr[index] < arr[R]) {// [index]和<区的下一个数交换,然后<区向右扩一个位置,index++ Swap(arr, ++less,index++); } else { // [index]和>区前一个数交换,>区左扩一个位置,index不变因为没有交换完的数没有看过 Swap(arr, index, --more); } } Swap(arr, more, R); // <[R] =[R] >[R] ,和最后一位划分指做交换 // less+1因为小于区域需要加一 才能到等于区域上,而大于区域已经和index撞上了不用加 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; }