快排实现方式1:
package com.kongge.com.testdemo;
public class QuickSort {
public static void main(String[] args) {
int [] nums = {6,1,2,5,9,3,4,7,10,8};
quickSort(nums);
for (int num : nums){
System.out.print(num +" ");
}
}
// 快速排序,a是数组,n表示数组的大小
public static void quickSort(int[] a) {
int n = a.length;
quickSortInternally(a, 0, n-1);
}
// 快速排序递归函数,p,r为下标
private static void quickSortInternally(int[] a, int p, int r) {
if (p >= r) return;
int q = partition(a, p, r); // 获取分区点
quickSortInternally(a, p, q-1);
quickSortInternally(a, q+1, r);
}
private static int partition(int[] a, int p, int r) {
int pivot = a[r];
int i = p;
for(int j = p; j < r; ++j) {
if (a[j] < pivot) {
if (i == j) {
++i;
} else {
int tmp = a[i];
a[i++] = a[j];
a[j] = tmp;
}
}
}
int tmp = a[i];
a[i] = a[r];
a[r] = tmp;
return i;
}
}
快排实现方式2:
package com.kongge.com.testdemo;
public class QuickSort2 {
public static void main(String[] args) {
int [] nums = {6,1,2,5,9,3,4,7,10,8};
quickSort(nums);
for (int num : nums){
System.out.print(num +" ");
}
}
// 快速排序,a是数组,n表示数组的大小
public static void quickSort(int[] a) {
int n = a.length;
quickSortInternally(a, 0, n-1);
}
// 快速排序递归函数,p,r为下标
private static void quickSortInternally(int[] a, int p, int r) {
if (p >= r) return;
int q = partition(a, p, r); // 获取分区点
quickSortInternally(a, p, q-1);
quickSortInternally(a, q+1, r);
}
public static int partition(int [] a,int left, int right) {
int i, j, t, temp;
temp = a[left]; //temp中存的就是基准数
i = left;
j = right;
while(i != j) { //顺序很重要,要先从右边开始找 i!=j表示两个指针未相遇
while(a[j] >= temp && i < j)
j--;
while(a[i] <= temp && i < j)//再找右边的
i++;
if(i < j)//交换两个数在数组中的位置
{
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
//最终将基准数归位 归位后,基准点左边都小于此时的基准,右边都大于此时的基准
a[left] = a[i];
a[i] = temp;
return i;
}
}
结论:
实现一,两个哨兵移动先后没有区别,因为两个哨兵在同一起点。
实现二,两个哨兵一个在数组首位置,一个在数组尾部,要注意移动的先后顺序,谁先移动与基准选取有关。
如果选取最左边的数arr[left]作为基准数,那么先从右边开始可保证i,j在相遇时,相遇数是小于基准数的,交换之后temp所在位置的左边都小于temp。但先从左边开始,相遇数是大于基准数的,无法满足temp左边的数都小于它。所以进行扫描,要从基准数的对面开始。(注:左右相对来说,也可前后)