- 快速排序双向指针思想,先找第一个为基准项,两个指针同时从最后一项和第一项一次i++和j–
- 右边的判断比基准项小的就暂停,左边的判断比基准项大的就暂停 此时此刻就交换左边i的位置的值和j的位置的值,再从右边遍历遇到小的暂停 ,左边遍历大的暂停 前提是i小于j
- 最后i==j 时候 就交换基准项和i的位置的值 这时候 基准项左边就是小于它的 ,右边就是大于它的 再把基准项左边和右边依次做递归,分开处理,最后就是完整的排序
第一种双向指针
public class FastkSort {
public static void quickSort(int[] arr, int low, int high) {
if(low>high){
return;
}
int i,j,temp;
i = low;
j = high;
temp = arr[i];//基准项也就是参考项
while(i<j){
//先从右边开始遍历
while (i<j&&arr[j]>=temp){
j--;//继续从后往前,记录指针位置
}
while (i<j&&arr[i]<=temp){//i<j是必要的 因为j-- 后生效
i++;//继续从前往后,记录指针位置
}
//都走到if了 说明右边遇到了比基准值小的
if(i<=j){
//二话不说交换位置
int t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
//走到这里说明i和j重合了 此时把基准项和重合的位置值交换 以基准项为切割点,再左右两边递归调用
arr[low] = arr[i];//把重合位置的值 交换
arr[i] = temp;
quickSort(arr,low,j-1);//因为基准项的值左边小,右边大 所以基准项可以不动
quickSort(arr,i+1,high);//因为基准项的值左边小,右边大 所以基准项可以不动
}
public static void main(String[] args) {
int[] arr = {10, 7, 2, 4, 7, 62, 3, 4, 2, 1, 8, 9, 19};
System.out.println("10, 7, 2, 4, 7, 62, 3, 4, 2, 1, 8, 9, 19");
quickSort_2(arr, 0, arr.length - 1);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
第二种快排 单指针
//第二种排序算法,经典的挖坑分治
public static void quickSort_2(int[] arr, int start, int end) {
if(start>=end){
return ;
}
int i , j ,temp;
i = start;
j = end;
temp = arr[start];
while(i<j){
//从右往左
while (i<j&&arr[j]>=temp){
j--;
}
if(i<j){
arr[i++] = arr[j];
}
//从左往右
while (i<j&&arr[i]<=temp){
i++;
}
if(i<j){
arr[j--] = arr[i];
}
arr[i] = temp;
quickSort_2(arr,start,i-1);
quickSort_2(arr,j+1,end);
}
}
}
个人认为第一种利用了双向指针的特性 找到最大或最小,再交换位置。
第二种是单项指针,右边小的交换,然后从左边开始左边大的再交换一次,交换是次数是第一种的两倍,效率是比不上第一种的。
推荐使用第一种双向指针特性快排