快速排序写了很多次了,但一直没有理解,今天重新写了一次,记录一下自己的理解
实现原理
快排的实现原理是给定一个基准,这个基准最好是数组里面存在的数(一般是第一个),进行如下操作。
- 从数组右边开始设置一个游标 j,j往左边走,每走一步与基准进行比较,如果比基准大,就继续往左边走,如果比基准小或者相等,则跟基准调换位置,调换位置之后,基准的下标就是j,原来 j下标位置的值就到了原来基准的位置。
- 再从数组左边设置一个游标i,i往右边走,每走一步与基准进行比较,如果比基准小,就继续往右边走,如果比基准大或者相等,则跟上一步调换过位置的基准位置(也就是j)调换位置,调换位置之后,基准的下标就是i,原来 i下标位置的值就到了第二步的j。
- 一直重复上面的1和2,就形成了左右两部分,左边的部分都比基准小,右边的都比基准大。
- 然后将左右两部分作为新的数组再次进行1,2,3的操作
- 直到每个数组只有一个数,完成排序
代码实现
public static void quickSort(int[] arr, int left, int right) {
//递归结束的条件,按照逻辑应该是两个游标相遇在一起就结束,这里写==也是可以的
if (left >= right) {
return;
}
//使用第一个作为基准,定义左右两个游标
int i = left, j = right, key = arr[left];
//左边游标小于右边游标
while (i < j) {
//从右边开始向左边遍历,找到比基准小的值索引
while (i < j && arr[j] >= key) {
j--;
}
//这个判断加不加对结果没有影响,只是为了避免两个相邻的数比较时无用的交换
if (i < j) {
//将基准和找到的这个值的索引进行互换,互换之后基准的索引到了j(右边)
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//这里可以看到基准到了右边的步骤
System.out.println(Arrays.toString(arr));
//从左边开始向右边遍历,找到比基准大的值索引
while (i < j && arr[i] <= key) {
i++;
}
//这个判断加不加对结果没有影响,只是为了避免两个相邻的数比较时无用的交换
if (i < j) {
//将基准和找到的这个值的索引进行互换,互换之后基准的索引到了i(左边)
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//这里可以看到基准到了左边的步骤
System.out.println(Arrays.toString(arr));
}
//i和j碰头就跳出循环了,此时基准的索引就是或者j
//对基准左边的继续排序
quickSort(arr, left, i - 1);
//对基准右边的继续排序
quickSort(arr, j + 1, right);
}
public static void main(String[] args) {
int[] arr = {5, 2, 6, 4, 7, 8, 1, 9, 3, -2, 13};
quickSort(arr, 0, arr.length - 1);
}