快速排序思路
- 选一个数,将这个数理解为中间数(又称基数),不断将小于其本身的数移到左边,大于其本身的数移到右边
- 边界条件: end-start<2
补充了解:
- 关于最后一个与基位交换的数,为什么必然是在左边,而不可能是在右边?
因为我们是先从右往左移动,满足在右边的数据应该就不会被右指针停留了。最后右指针停留的数必然是在基数左边的- 双指针循环中是否需要包含被选择数本身?
- 不包含的话,若本身是最值,则在最后交换数据的时候可能会比较麻烦处理,建议包含。麻烦的原因如下:
balabalbala
3 .内部循环是否要判断等于本身的数?
1. 若等于本身,是否需要停?
等于的数,其实在左边、右边影响不大,加入判断条件,可以让指针移动的更快,提高
2. 若是不判断:
当处理值中出现相同值,处理起来会很麻烦 。。。 原因如下:
asdsa
核心代码:
public static void main(String[] args){
int[] nums = {2,1,3,4,6,5,11,2,5,7};
quickSort(nums,0,nums.length);
for(int i =0;i<nums.length;i++){
System.out.print(nums[i]);
System.out.print(",");
}
}
public static void quickSort(int[] nums,int left,int right){
if(right-left<2){
return;
}
int base = nums[left];
int i=left,j=right-1;
while(i!=j){
while(nums[j]>=base && j>i){
j--;
}
while(nums[i]<=base && j>i){
i++;
}
if(j>i){
Helper.swap(nums,j,i);
}
}
nums[left] = nums[j];
nums[j] = base;
// 为什么i不用-1?因为左闭又开呀。i并不会作为一个下标被取到
quickSort(nums,left,i);
quickSort(nums,i+1,right);
}
//学习的代码
//更巧妙的一个方法。判断左边的数大于右边的,就将左边的数换到右边,同时右边的指标往前移动
// 这样最后i,j停留的位置就会变成第一个大于基数的数的位置。所以后面的操作需要i-i
public static void quickSort2(int[] nums,int left,int right){
if(right-left<2){
return;
}
int base = nums[left];
int i=left+1,j=right;
while(i!=j){
if(nums[i]<base){
i++;
}else {
Helper.swap(nums,i,--j);
}
}
// i 会停在一个比base大的数上面
// 所以交换的时候,应该是i-1的位置和起始位置进行交换
Helper.swap(nums,i-1,left);
// 为什么i不用-1?因为左闭又开呀。i并不会作为一个下标被取到
quickSort(nums,left,i-1);
quickSort(nums,i,right);
}