分析
快排相当于在数组最左边和数组最右边定义两个指针,将数组第一个元素定义为key。
左指针负责将定位到的<key的元素全部丢到右边,右指针负责将定位到的<=key的元素全部丢到左边。
这样一来,当循环结束后,将key值和两个指针重叠的数值进行交换后,所有左边的元素都<=key,而所有右边的元素都>key。然后再重复以上做法,将key左边的数组进行同样的算法排序,右边也一样。
示例流程
这里我们以{1,2,4,5,7,4,5,3,0}为例进行分析。首先对{1,2,4,5,7,4,5,3,0}进行排序:
1.一开始i指向a[0],j指向a[a.length-1],key=a[0]
-
当(a[j] > key && i < j) j--,即左移指针;
-
当(a[i] <= key && i < j) i++,即右移指针;
-
当i < j时,交换a[i]和a[j]位置;
-
当i = j,触发条件直接跳出while循环,并进行key值调整。
key
1 2 4 5 7 4 5 3 0
i j
第一次while循环(最外圈的while循环):
1 2 4 5 7 4 5 3 0
i j
当i < j时,交换a[i]和a[j]位置:
1 0 4 5 7 4 5 3 2
i j
第二次while循环:
key
1 0 4 5 7 4 5 3 2
i j
1 0 4 5 7 4 5 3 2
i
j
i = j,触发条件直接跳出while循环,进行key值调整:
0 1 4 5 7 4 5 3 2
i
j
key
这样一来,key左边的都是小于key的,而key右边的都是大于key的。
再进行左边{0}和右边{4,5,7,4,5,3,2}两个数字的快排。流程如上。
2.对左边数组{0}排序,i,j皆为指针。
key
0
i
j
i = j,触发条件直接跳出while循环,进行key值调整。因为 i=j,所以交换后0还是0
3.对左边数组{4,5,7,4,5,3,2}排序,i,j皆为指针。
-
当(a[j] > key && i < j) j--,即左移指针;
-
当(a[i] <= key && i < j) i++,即右移指针;
-
当i < j时,交换a[i]和a[j]位置;
-
当i = j,触发条件直接跳出while循环,并进行key值调整。
key
4 5 7 4 5 3 2
i j
第一次while循环:
4 5 7 4 5 3 2
i j
i < j时,交换a[i]和a[j]位置:
4 2 7 4 5 3 5
i j
4 2 7 4 5 3 5
i j
i < j时,交换a[i]和a[j]位置:
4 2 3 4 5 7 5
i j
4 2 3 4 5 7 5
j
i
当i = j,触发条件直接跳出while循环,并进行key值调整。
现在4左边的数字都<=4,4右边的都>4,分为了{4,2,3}和{5,7,5}两个数组,对左右进行分别采用上面方法一样递归排序即可。下面省略了分析流程。
代码:
package com.quicksort;
import java.util.Arrays;
public class QuickSort {
public static void main(String[] args) {
int[] a = {1, 2, 4, 5, 7, 4, 5 ,3 ,9 ,0};
System.out.println(Arrays.toString(a));
quickSort(a);
System.out.println(Arrays.toString(a));
}
public static void quickSort(int[] a) {
if(a.length>0) {
quickSort(a, 0 , a.length-1);
}
}
private static void quickSort(int[] a, int low, int high) {
//1,找到递归算法的出口
if( low > high) {
return;
}
//2, 存
int i = low;
int j = high;
//3,key
int key = a[ low ];
//4,完成一趟排序
while( i< j) {
//4.1 ,从右往左找到第一个小于key的数
while(i<j && a[j] > key){
j--;
}
// 4.2 从左往右找到第一个大于key的数
while( i<j && a[i] <= key) {
i++;
}
//4.3 交换
if(i<j) {
int p = a[i];
a[i] = a[j];
a[j] = p;
}
}
// 4.4,调整key的位置
int p = a[i];
a[i] = a[low];
a[low] = p;
//5, 对key左边的数快排
quickSort(a, low, i-1 );
//6, 对key右边的数快排
quickSort(a, i+1, high);
}
}