分治+指针交换法
快排思想:
1、给这组数据找一个基准位(一般是数组的第一位)pivot。
2、以基准位把数组分为2个子串,左边的的数据都小于等于基准位,右边的数据都大于等于基准位。
3、以同样的方式别对2个子串进行此方法排序,一直递归,直到数据排好顺序。
递归的结束条件:需要递归的子串数组只有一个数据。
给定原始数列如下,要求从小到大排序:
开局和挖坑法相似,我们首先选定基准元素Pivot,并且设置两个指针left和right,指向数列的最左和最右两个元素:
接下来是第一次循环,从right指针开始,把指针所指向的元素和基准元素做比较。如果大于等于pivot,则指针向左移动;如果小于pivot,则right指针停止移动,切换到left指针。
在当前数列中,1<4,所以right直接停止移动,换到left指针,进行下一步行动。
轮到left指针行动,把指针所指向的元素和基准元素做比较。如果小于等于pivot,则指针向右移动;如果大于pivot,则left指针停止移动。
由于left一开始指向的是基准元素,判断肯定相等,所以left右移一位。
由于7 > 4,left指针在元素7的位置停下。这时候,我们让left和right指向的元素进行交换。
接下来,我们进入第二次循环,重新切换到right向左移动。right先移动到8,8>2,继续左移。由于2<8,停止在2的位置。
切换到left,6>4,停止在6的位置。
元素6和2交换。
进入第三次循环,right移动到元素3停止,left移动到元素5停止。
元素5和3交换。
进入第四次循环,right移动到元素3停止,这时候请注意,left和right指针已经重合在了一起。
当left和right指针重合之时,我们让pivot元素和left与right重合点的元素进行交换。此时数列左边的元素都小于4,数列右边的元素都大于4,这一轮交换终告结束。
代码实现
public class QuickSort000 {
public static void quickSort(int[] arr,int low,int high){
int i,j,pivot,t;
if(low>high){ return;} //递归的终止条件,即需要排的子串个数为1
i=low;
j=high;
pivot = arr[low]; //pivot就是基准位
while (i<j) {
while (pivot<=arr[j]&&i<j) {j--;}//先看右边,依次往左递减
while (pivot>=arr[i]&&i<j) {i++;}//再看左边,依次往右递增
if (i<j) { //如果满足条件则交换
t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
System.out.println("i="+i+"j="+j);
arr[low] = arr[j]; //取右边的j的下标,最后将基准为与i和j相等位置的数字交换
arr[j] = pivot;
quickSort(arr, low, i-1); //递归调用左半数组
quickSort(arr, i+1, high);//递归调用右半数组
}
public static void main(String[] args){
int[] arr = {6 ,1, 2, 7, 9 ,3 ,4, 5 , 8};
quickSort(arr, 0, arr.length-1);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
}
超级好图