快排的作用:
从i 到 j 这段内每次经过一次快排就能 让首元素找到合适的位置k(i<=k<=j),于是就分成了(i 到 k-1)和(k+1到j)两端 没有排序好
例题
有如下数组
27 | 99 | 0 | 8 | 13 | 64 | 86 | 16 | 7 | 10 | 88 | 25 | 90 |
i | j |
取出首元素(第一个元素)以及两个指针 i 和 j,分别指向99 和 90
i 找 比首元素27大 的元素(比首元素小则 i 往后移动 ),j 找 比首元素27小 的元素(比首元素大则 j 往前移动),
如果满足了 i,j 的条件则 将元素 调换位置,然后继续找,直至i>=j为止,此时 i 的位置就是首元素合适的位置
99比27大,满足条件 ,i 不变位置;比较 j 位置 90 发现比27大,不满足条件,则 j 往前移动,发现 25 满足条件;
将99和25(此时i ,j 指向的元素)对调位置,变成如下
27 | 25 | 0 | 8 | 13 | 64 | 86 | 16 | 7 | 10 | 88 | 99 | 90 |
i | j |
同样的步骤,执行依次会有如下的结果
27 | 25 | 0 | 8 | 13 | 64 | 86 | 16 | 7 | 10 | 88 | 99 | 90 |
i | j |
对换位置:
27 | 25 | 0 | 8 | 13 | 10 | 86 | 16 | 7 | 64 | 88 | 99 | 90 |
i | j |
27 | 25 | 0 | 8 | 13 | 10 | 86 | 16 | 7 | 64 | 88 | 99 | 90 |
i | j |
对换位置:
27 | 25 | 0 | 8 | 13 | 10 | 7 | 16 | 86 | 64 | 88 | 99 | 90 |
i | j |
27 | 25 | 0 | 8 | 13 | 10 | 7 | 16 | 86 | 64 | 88 | 99 | 90 |
i=j |
满足i>=j对换i和首元素的位置
16 | 25 | 0 | 8 | 13 | 10 | 7 | 27 | 86 | 64 | 88 | 99 | 90 |
i=j |
此时会发现 27左边的元素都比27小,右边的比27大
分成两段于是重复执行上面的步骤就可以得到排序好的数组
算法:递归伪代码,swap交换元素位置的 函数需要自己实现
quickSort(ArrayList arr,int i,int j,int k,int m){//k是首元素的下标,m是末尾元素下标
if(i>=j){
swap(arr[k],arr[i]);//对调首元素和i的位置、i位置就是首元素排序好后的位置
quickSort(arr, k, i-1, k, i-1);//快排i前面的,k(首元素位置没变) 到i-1(新的末尾元素位置)
quickSort(arr, i+1, m, i+1, m);//快排i后面的 i+1(新的首元素位置) 到 m(末尾元素m没有变)
return;
}
if(arr[i] > arr[k] && arr[j] < arr[k]){
swap(arr[i],arr[j]); //1、两条件都满足 交换i,j元素位置
return;
}else if(arr[i] > arr[k] && arr[j] > arr[k]){
quickSort(arr,i,j-1,k,m); //2、j不满足往前移动
}else if(arr[i] < arr[k] && arr[j] < arr[k]){
quickSort(arr,i+1,j,k,m); //3、i不满足往后移动
}else{ //都不满足则都移动
quickSort(arr,i+1,j-1,k,m); //4、 i,j都对应移动
return;
}
}