Skip to content

Commit e9fc8fc

Browse files
committed
sort、partition写法参照<<程序员面试金典>>重写
1 parent cb906cf commit e9fc8fc

1 file changed

Lines changed: 37 additions & 31 deletions

File tree

base/src/main/java/sort/QuitSort.java

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,55 +13,61 @@
1313
* 左数组元素小于等于切分元素,右数组大于等于切分元素,
1414
* 将左右子数组排序,整个数组也就有序了
1515
*
16+
* 平均情况为O(nlog(n)),最差情况O(n~2),存储空间O(log(n))
17+
* V1.1.0 sort、partition写法参照<<程序员面试金典>>重写
18+
*
1619
* @author Jian Shen
17-
* @version V1.0.0
20+
* @version V1.1.0
1821
* @date 2019/7/23
1922
*/
2023
public class QuitSort<T extends Comparable<T>> extends Sort<T> {
2124

2225
@Override
23-
public void sort(@NotNull T[] array) {
24-
shuffle(array);
25-
sort(array, 0 , array.length - 1);
26+
public void sort(@NotNull T[] arr) {
27+
shuffle(arr);
28+
sort(arr, 0 , arr.length - 1);
2629
}
2730

28-
private void sort(T[] array, int left, int right) {
29-
if (right <= left) {
30-
return ;
31+
private void sort(T[] arr, int left, int right) {
32+
int index = partition(arr, left, right);
33+
if (left < index - 1) { // 排序左半部分
34+
sort(arr, left, index - 1);
35+
}
36+
if (index < right) { // 排序右半部分
37+
sort(arr, index, right);
3138
}
32-
int middle = partition(array, left, right);
33-
sort(array, left, middle - 1);
34-
sort(array, middle + 1, right);
3539
}
3640

37-
private int partition(T[] array, int left, int right) {
38-
int i = left;
39-
int j = right + 1;
40-
T k = array[left];
41-
while (true) {
42-
while (less(array[++i], k) && i != right); // 循环1,直到找到大于等于k的元素或i增加为right
43-
while (less(k, array[--j]) && j != left); // 循环2,直到找到比小于等于k的元素或j减小为left
44-
if (i >= j) {
45-
break;
41+
private int partition(T[] arr, int left, int right) {
42+
T pivot = arr[(left + right) / 2]; // 挑选一个基准点
43+
while (left <= right) {
44+
// 找到左边应被放到右边的元素
45+
while (arr[left].compareTo(pivot) < 0) {
46+
left++;
47+
}
48+
// 找到右边应被放到左边的元素
49+
while (arr[right].compareTo(pivot) > 0) {
50+
right--;
51+
}
52+
if (left <= right) {
53+
swap(arr, left, right); // 交换元素
54+
left++;
55+
right--;
4656
}
47-
swap(array, i, j); // 交换当前轮次找到的元素
4857
}
49-
// array[left]必定小于等于array[j], happens-before原则,前置条件为break执行,
50-
// break前置条件为循环2执行完毕,故需交换从而保证当前切分元素必定大于等于左侧数组值,小于等于右侧数组值
51-
swap(array, left, j);
52-
return j;
58+
return left;
5359
}
5460

55-
private void shuffle(T[] array) {
56-
List<Comparable> list = Arrays.asList(array);
57-
Collections.shuffle(list); // 防止最坏的情况,第一次从最小的元素切分,第二次从次小的元素切分。时间复杂度N^2/2
58-
list.toArray(array);
61+
private void shuffle(T[] arr) {
62+
List<Comparable> list = Arrays.asList(arr);
63+
Collections.shuffle(list); // 防止最坏的情况,第一次从最小的元素切分,第二次从次小的元素切分。时间复杂度N^2
64+
list.toArray(arr);
5965
}
6066

6167
public static void main(String[] args) {
6268
Sort sort = new QuitSort();
63-
Integer[] array = new Integer[]{2, 1, 4, 6, 3, 7, 3};
64-
sort.sort(array);
65-
System.out.println(Arrays.asList(array));
69+
Integer[] arr = new Integer[]{2, 1, 4, 6, 3, 7, 3};
70+
sort.sort(arr);
71+
System.out.println(Arrays.asList(arr));
6672
}
6773
}

0 commit comments

Comments
 (0)