注意事项:
基准点在左,则while(l<r)从右边开始
基准点在右,则从左边开始;
两种实现方式:
1.基于原生的思路
import java.util.Arrays;
import java.util.Random;
public class 快速排序 {
//快排的关键点是:左侧找基准点的话,从右侧开始遍历,即反向的!
public static void main(String[] args) {
int a[] = {5, 2, 3, 1};
quicksort(a, 0, a.length - 1);
System.out.println("==============================");
quicksort1(a, 0, a.length - 1);
}
static Random random = new Random();
//原生快排,不使用双指针
public static void quicksort(int a[], int l, int r) {
if (l >= r) return;
int ll = l;
int rr = r;
// int rand = random.nextInt(r - l + 1) + l;
// {
// int s = a[rand];
// a[rand] = a[l];
// a[l] = s;
// }
int m = a[l];
while (l < r) {
while (a[r] >= m && l < r) //从最右边开始,找小于基准值的,如果大于基准值,就next
r--;
if (a[r] < m) //如果找到了小于基准值的,就把该值放入基准位置,a[r]就是冗余值了,可以被覆盖
a[l] = a[r];
while (a[l] <= m && l < r) //从l开始找大于基准值的,找到了之后放入a【r】的位置
l++;
if (a[l] > m)
a[r] = a[l];
}
// 循环出来的时候,肯定是l==r,且该位置是冗余值,是两边的分界线
a[l] = m;
System.out.println(Arrays.toString(a));
quicksort(a, ll, l - 1);
quicksort(a, l + 1, rr);
}
//双指针
public static void quicksort1(int a[], int l, int r) {
if (l >= r) return;
int m = a[l];
int ll = l, rr = r;
// 双指针法,不需要每次找到需要挪动的值的时候就直接挪动,而是等到l和r均找到符合条件的值之后,进行交换
while (l < r) {
while (l < r && a[r] >= m)
r--;
while (l < r && a[l] <= m)
l++;
if (l != r) { //走到此处,则l和r点的两侧都是合适的位置,当l!=r的时候,说明是两个不同的值,则需要交换
int t = a[r];
a[r] = a[l];
a[l] = t;
}
//再接着进入循环,直到l==r
}
a[ll] = a[l];
a[l] = m;
System.out.println(Arrays.toString(a));
quicksort1(a, ll, l - 1);
quicksort1(a, l + 1, rr);
}
}