针对上一次代码的改进,以及二者的区别加以描述:
1,第一种快排方式是外层循环从右至左的指针r,和从左至右的指针l,指向同一索引值,再进行交换,此刻二者指向索引处的值必定是小于或者等于基准值的,从而在外层循环结束后再次进行值的交换,确保交换后的值使再其左侧都是小于基准值,而右侧都是大于基准值,然后在递归调用该方法,即递推使得排序的规模一直在减少,直至数据规模为1,进行回归;
2.第二种快速排序的方式是以值的覆盖形式完成,外层循环条件依旧直至ij相等,而内层循环是从右至左找比基准值小的数据,然后直接将a[l] = a[r],从左至右是直接找比基准值大的值,找到之后将a[r] = a[l],最终外层循环结束之后,lr指向同一索引,将备份好的a[l]值即temp,覆盖到l/r指向的索引处
二者的区别:外层循环结束的交换,值必然是小于或等于基准数的,而这次的代码,覆盖的值就不一定是小于(小循环多次,i未找到使两者重合),等于的情况是(r一次找到)r找到,而i未找到,有可能的大于(i找到比基准值大的例如(4,5,1,6))
代码如下:
import java.util.Arrays; public class QuickSort2 { public static void sort2(int[] a,int left,int right){ if(left>=right){ return; } int l =left; int r =right; int temp = a[left]; while(l<r){ while(l<r&&a[r]>=temp){ r--; } //执行完毕该循环,两种情况:r=l,r指向中间的某个节点 if(r!=l){ a[l] = a[r]; } while (l<r&&a[l]<=temp){ l++; } //执行完毕该循环,两种情况,r=l,或l指向中间的某个节点(找到比基准点大的,而此时的r指向的小于基准点) if(l!=r){ a[r]= a[l]; } } //外层循环结束后,ij指向同一节点,r此时的左侧都是小于基准点的,右侧都是大于基准点的 a[l] = temp; System.out.println(Arrays.toString(a)); sort2(a,left,l-1); sort2(a,l+1,right); } public static void main(String[] args) { int[] a ={4,1,2,3,8}; sort2(a,0,a.length-1); } }