快速排序
快速排序的基本思想是:
- 选择一个排序的切分点,对剩余的部分进行从前至后的遍历
- 从左边开始向右,找到第一个比切分点大的值
- 从右边开始向左,找到第一个比切分点小的值
- 交换两个值的位置
- 这样保证切分点左边比切分点小,右边比切分点小
- 同时交换的前提是两个指针不发生碰撞(相遇) — 假定了切分点是在中间
- 这里将第一个位置作为切分点,因此还需要返回切分点的具体位置
- 在碰撞发生后,切分循环退出,这时需要交换低位(low)与碰撞的h
- 因为发生碰撞时,h是不大于l的,需要交换两个低位值,所以交换的是h和l(这里有点不清楚)
- 在碰撞发生后,切分循环退出,这时需要交换低位(low)与碰撞的h
代码实现:
public static void sort(int[] arr, int low, int high) {
if (low >= high) return;
int p = partition(arr, low, high);
// 对左半部分和右半部分切分,不包括切分点
sort(arr, low, p - 1);
sort(arr, p + 1, high);
}
private static int partition(int[] arr, int low, int high) {
int l = low, h = high + 1; // 取low可以不包括切分点
int v = arr[l]; // 切分点
while (true) {
// 找到较大值和较小值的位置,左半部分找较大值,右半部分找较大值,再进行交换
// 保证右边的都是较大值,左边的都是较小值
while (v > arr[++l] && l != high) ;
while (v < arr[--h] && h != low) ;
// 相遇则退出
if (l >= h) break;
// 不断交换满足条件的值
swap(arr, l, h);
}
// 此时指针相遇,交换低位,因为是选择低位作为切分点
swap(arr, low, h);
return h;
}
// 用于交换的数组两个位置的值
private static void swap(int[] arr, int a, int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}