平均T=O(nlogn) 最坏Tmax=O(n^2)
基本思想:
简记:
以最左端元素为分划元素(主元),然后
左找大,右找小;
调换后继续找;
越界后停止查找和调换。最后,
调位主元和l[j],再在主元前后继续分划。
代码:
1 | public class QuickSortTest { |
另一种写法:
(基本思想是一样的,只是将主元从arr[left]换成了arr[right],且分划函数Partition的主循环也从三个do-while循环换成了三个while循环)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41public class quickSortTest {
private static void recQuickSort(int arr[], int left, int right) {
if (right - left <= 0) {
return;
} else {
int pivot = arr[right]; //一般使用数组最右边的元素作为枢纽
int partition = partitionIt(arr, left, right, pivot);
recQuickSort(arr, left, partition - 1);
recQuickSort(arr, partition + 1, right);
}
}
/**
* 划分:
* 划分是快速排序的根本机制,划分本身也是一个有用的操作。
* 划分数据就是把数据分为两组,使所有关键字大于特定值的数据项在一组,所有关键字小于特定值的数据项在另一组。
*/
private static int partitionIt(int[] arr, int left, int right, int pivot) {
int leftPtr = left-1;
int rightPtr = right; //使用最右边的元素作为主元枢纽,划分时就要将最右端的数据项排除在外
while (true) {
while (arr[++leftPtr] < pivot); //从前往后找到不比arr[right]小的元素时停止;或当自增的leftPtr=right时,arr[leftPtr]=pivot=arr[right]会自动停止循环
while (rightPtr > 0 && arr[--rightPtr] > pivot); //从后往前找不比arr[right]大的元素时停止;这个需要手动添加循环终止条件rightPtr>0以防角标越界。
if (leftPtr >= rightPtr) {
break;
} else {
// 交换leftPtr和rightPtr位置的元素
int temp = arr[leftPtr];
arr[leftPtr] = arr[rightPtr];
arr[rightPtr] = temp;
}
}
// 交换leftPtr和right位置的元素
int temp = arr[leftPtr];
arr[leftPtr] = arr[right];
arr[right] = temp;
return leftPtr;// 返回枢纽位置
}
}