用以下例子描述快排过程,假设要从小到大排序
待排序:5 7 1 8 4
从左端(可为任意一端)取出基数base=5,此时左指针l=0,右指针r=4
5 7 1 8 4 5
l=0 r=4
从右指针开始向左找,找出比base=5小的数,找到4,将4赋值给左指针的数,然后开始从左指针找
4 7 1 8 4
l=0 r=3
从左指针开始向右找,找出比base=5大的数,找到7,将7赋值给右指针的数
4 7 1 8 7
l=2 r=3
从右指针开始向左找,找出比base=5小的数,右指针r=3左移一位r=2和左指针重合,不再进行比较,停止此次排序,将base=5赋值给左右指针重合的位置
4 1 5 8 7
l=2 r=2
此时可发现base左边的数均小于base右边的数
再对base左右两边的数组进行同样操作
public class Main {
public static void main(String[] args) {
List<Integer> arr = new ArrayList<Integer>();
arr.add(5);
arr.add(7);
arr.add(1);
arr.add(3);
arr.add(8);
arr.add(4);
arr.add(6);
sort(0, arr.size() - 1, arr);
System.out.println(arr.toString());
}
public static void sort(int left, int right, List<Integer> arr){
//这里选择左端数字为基数
int base = arr.get(left), initLeft = left, initRight = right;
//所以这里从右端指针开始移动
boolean isLeft = false;
//左右指针相等,完成一次排序
while (left < right){
//从左指针开始移动
if(isLeft){
//左指针所在数大于base,将其赋值给右指针所在数
if(arr.get(left) > base){
arr.set(right, arr.get(left));
isLeft = !isLeft;
}else{
left++;
}
//从右指针开始移动
}else{
//右指针所在数小于base,将其赋值给左指针所在数
if(arr.get(right) < base){
arr.set(left, arr.get(right));
isLeft = !isLeft;
}else{
right--;
}
}
}
arr.set(left, base);
if(left - initLeft > 1){
sort(initLeft, left-1, arr);
}
if(initRight - left > 1){
sort(left+1, initRight, arr);
}
}
}
时间复杂度O(nlogn),最坏情况下O(n^2)