算法描述
快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:
- 从数列中挑出一个元素,称为 “基准”(pivot);
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序
动图演示
代码实现
public class Quick {
public static int[] arr = {1, 3, 5, 2, 11, 23, 34, 31, 12, 11};
public static int count = 0;
public static void sort(int[] arr, int l, int r) {
if (left < right) {
//左指针,右指针,选择的比较因子
int leftPointer, rightPointer, factor;
leftPointer = left;
rightPointer = right;
//选左边元素作为比较因子
factor = arr[leftPointer];
//当左右指针没有重合的时候
while (leftPointer < rightPointer) {
//当左右指针没有重合,且右指针指向元素大于比较因子
while (leftPointer < rightPointer && arr[rightPointer] > factor) {
//将右指针向最左移动一次
rightPointer--;
}
//当左右指针重合或者右指针指向元素小于比较因子的时候
if ((leftPointer < rightPointer)) {
//将右指针指向的元素的值赋值给此时的左指针指向的元素
//这里不要误解数组值会被覆盖,此时被赋值的元素其实是比较因子,所以不会造成数据的丢失
arr[leftPointer++] = arr[rightPointer];
}
//经过上面两个步骤后,右边比比较因子小的数被置换到了左边
//继续判断,此时左右指针未重合,且左指针指向的元素比比较因子小的时候,让左指针向右移动一次
while (leftPointer < rightPointer && arr[leftPointer] < factor) {
leftPointer++;
}
//将左指针指向的比比较因子大的数放到右边
if (leftPointer < rightPointer) {
arr[rightPointer--] = arr[leftPointer];
}
//经过此步骤之后,左边放的是比比较因子小的数,右边放的全部是大于比较因子的数
//这时候就可以把取出来的比较因子重新放回到数组里面了
//此时的数组是按照比较因子分隔的
arr[leftPointer] = factor;
//继续递归数组左边比比较因子小的部分,直到左指针和右指针重合,也就是左指针和右指针重合的时候
sort1(arr, left, leftPointer - 1);
//同上
sort1(arr, leftPointer + 1, right);
}
}
}
public static void main(String[] args) {
sort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
}