快速排序
快速排序在排序策略中依旧采用分治的思想。但是以分治概括有点笼统,所以,自我总结一个思想即 挖坑填坑+ 分治。
算法思想:
1)为一个数字找到他的适合位置。(挖坑+填坑)
所谓适合位置就是,它左边的所有数字都比它,,右边的数字都比它大,即中间位 置。
2)分治
a. 对该数字左边的数组进行快速排序
b.对该数字右边的数组进行快速排
实例:
给定一个数字数组src[32,2,10,11,3,4,7,98,77]
a.首先从第一个数字开始i = 0; 讲第一个数字挖出来(挖坑),那么src[i]是一个坑,需要 用其他数字为它填充,用x标记x=src[i];
32,2,10,11,3,4,7,98,77
i j
从j开始,从右向左找出第一个比x小的数字,挖出来,填到上一个坑中,即使 src[i],首先 找到7,则将7填到src[0]位置,并且i++,src[j]就是个坑,需要其他 数字来填。
7,2,10,11,3,4,7,98,77
i j
b.从i开始找。找出第一个比x大的数字,填到src[j]位置。一直找到i=j为止,没有找到,那么讲x填到src[j]这个坑中。那么x这个位置,就是最合适的位置,它左边的数字都比它小,右边的数字都比它大。
7,2,10,11,3,4,32,98,77
ij
c.分治。
对src[j]左边的数字进行步骤a,右边的数字重复步骤a,
测试代码:
//排序的方法
/**
* 对源数组进行快速排序
* 挖坑-填坑
* @param src 源数组
* @param l 源数组的左边界
* @param r 源数组的右边界
*/
public static void sort(int[] src,int l,int r){
if(l < r){
System.out.println(l +" "+ r);
int i = l;
int j = r;
int x = src[l]; //旗标 ,为x找到合适的位置,即x的左边都比它,小,右边都比它大
//先从i右边找比i位置小的数字
while(i < j){
while(i < j && x < src[j]){
j--; //从右向左找,找比x小的数字
}
if(i <j){ //找到
src[i++] = src[j]; //挖src[j]坑,填src[i]坑
System.out.println("<--- i = "+(i-1)+" j= "+ j +" " +Arrays.toString(src));
}
//如果i仍然比j小的话,还可以继续寻找
while(i < j && x > src[i]){
i ++;
}
if(i < j){
src[j--] = src[i]; //挖src[i] 坑,填src[j]坑
// System.out.println(Arrays.toString(src));
System.out.println("----> i = "+i+" j= "+ (j+1) +" " +Arrays.toString(src));
}
}
//一直找到i == j的时候,为x的合适位置
if(i == j){
src[i] = x;
//然后采用分治法,对左边,右边的排序,
sort(src,l,i-1);
sort(src,i+1,r);
}
}
}
调用排序方法: int[] a = new int[]{32,1,2,10,98,70,23,24};
sort(a,0,a.length-1);