快速排序在许多竞赛,面试中经常考一个项目,常以填空,算法形式出现
static void quickSort(int[] arr,int begin,int end) {//分成若干个左子问题,右子问题
if(begin<end) {
int q = partition(arr,begin,end);
quickSort(arr, begin, q-1);
quickSort(arr, q+1, end);
}
}
那么重点就是如何去划分,左边的比主元小于或等于,右边的比主元大
代码思路
扫描指针小于等于主元的时候扫描指针往后走
扫描指针大于主元的时候扫描指针的值和末指针交换,末指针向左走
static int partition(int[] arr,int begin,int end){
int pivot = arr[begin];
int left = begin+1;
int rigth = end;
while(left >= end){//左右两个指针错开时退出
if(arr[left] <= pivot){//左指针小于等于主元左指针++
left++;
}else{//大于的时候和末指针交换,末指针++
int t = arr[left];arr[left] = arr[rigth];arr[rigth]=t;
rigth--;
}
}//左指针最后一次一定在大于主元的值上
//右指针最后一次一定在小于等于主元的值上
//所以循环退出后主元和右的值交换
int t = arr[rigth];arr[rigth] = arr[begin];arr[begin]=t;
return rigth;
}
完整代码
public class _快速排序单向扫描分区法 {
public static void main(String[] args) {
int[] arr = util.getRandomArr(10, 1, 20);
quickSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
static void quickSort(int[] arr ,int begin,int end) {
if(begin<end) {
int q = partition(arr,begin,end);
quickSort(arr,begin,q-1);
quickSort(arr,q+1,end);
}
}
//切一刀,确定主元,左边必然比主元小,右边必然比主元大
static int partition(int[] arr,int begin,int end) {
int pivot = arr[begin];
int sp = begin + 1;
int bigger = end;//两个值必然是相交错开的
while(sp <= bigger) { //前后两个指针错开
if (arr[sp] <= pivot) { //扫描指针小于主元,指针前进
sp++;
}else {//大于主元 则扫描指针的值和bigger值交换 bigger指针前进
util.swap(arr, sp, bigger);
bigger--;
}
}
util.swap(arr, begin, bigger);//最后一次两个指针重合比较指针的值,不管是大于还是小于
return bigger;
}
/*
* 最后一次两个指针重合比较指针的值
* 不管是大于还是小于
* 如果是大于 sp 则++,主元比较大,主元和 重合值 交换 bigger 主元左边是比主元小的
* 如果是小于 bigger-- 主元比较小, 那么就是 重合值-- 得左边一个交换
* 总结 :大于 主元 交换 重合值
* 小于 主元 交换 重合值左边一个交换
*/
}