import java.util.Arrays;
class Solution {
public int[] quickSort(int[] array) {
int[] ans = array.clone();
quickSort(0 , ans.length - 1, ans);
System.out.println(Arrays.toString(ans));
return ans;
}
public void quickSort(int l, int r, int[] array) {
if(l >= r) return;
// 每次用数组最右的数作为标志位
int cur = array[r];
int i = l;
int j = r - 1;
// 为什么这里 用 <= 后面分析
while(i <= j) {
//从 左到右 找到大于 cur的数
int lVal = array[i];
if(lVal <= cur) i++;
//从 右到左 找到小于 cur的数
int rVal = array[j];
if(rVal >= cur) j--;
// 当左指针指向的数大于 cur 且 右指针指向的数小于 cur 交换两个数字
if(lVal > cur && rVal < cur) {
int temp = array[j];
array[j--] = array[i];
array[i++] = temp;
}
}
//while循环执行下来,当 i > j 的时候。 经过 i处理的 左边 全部小于 cur ,经过 j处理的右边全部都大于 cur
//举个例子 一开始 数组 是 [1, 5, 2, 11, 12, 8, 4, 3, 9, 7]; cur = 7;
//从左边 开始 1 5 2都比 7 小 i++; 直到 i = 3 val = 11的时候
//从右边 开始 9 比 大 j--, 直到 j = 7 val = 3 的时候
// 交换 索引下标 i , j的值 [1, 5, 2, `3`, 12, 8, 4, `11` , 9, 7];
// 继续 12 和 4 换 [1, 5, 2, `3`, `4`, 8, `12`, `11` , 9, 7];
// 当 i 和 j 都到了 中间 索引位置 6 值为 8的地方。 发现 8 比 7 大, j--; 所以 i > j == true 跳出循环。 所以要做 i <= j 重合时候也是需要处理的
/* [1, 5, 2, `3`, `4`, 8, `12`, `11` , 9, 7]
* J I
* */
// 现在明白 一开始那句话没 经过 i处理的 左边 全部小于 cur ,经过 j处理的右边全部都大于 cur
//上图是执行完while后数组的状态。。我们让 最右标志位 7 和 i 位置 8 交换 位置
int temp = array[i];
array[i] = cur;
array[r] = temp;
// [1, 5, 2, `3`, `4`, `7`, `12`, `11` , 9, `8`];那么对于 7 来说,它的左边都是比他小的数,它的右边都是比他大的数,那么7的位置就已经被确定下来了
// 为什么确定下来了, 因为 比他 小的 都在 在 左边了,个数是一定的,不管有没有序,他也就那么多个,7就站这里了,同理 它的右边一样。
// 到这里,我们对 7 排好序了。那么乱序的数组 就分成了 左边 [1, 5, 2, `3`, `4`] 和 右边 [`12`, `11` , 9, `8`];递归调用,就能完成全部步骤
// 如何跳出循环, 左边界 == 右边界, 数组只有一个元素的时候,跳出循环。
// 回到重点, 左边 [1, 5, 2, `3`, `4`] 和 右边 [`12`, `11` , 9, `8`];
// 那么他们的 边界怎么定义
// 从 左边开始
/* [1, 5, 2, `3`, `4`]
l j
* */
// 从 右边开始
/* [`12`, `11` , 9, `8`]
i+1 r
* */
quickSort(l, j,array);
quickSort(i + 1, r,array);
}
public static void main(String[] args) {
new Solution().quickSort(new int[]{1, 5, 2, 11, 12, 8, 4, 3, 9, 7});
}
}
个人快速排序代码
于 2021-11-05 13:56:04 首次发布