什么是快速排序呢?
用一句话来说就是选取一个数,让该数左边的数据都比它小,右边的数据都比它大。
// 确定目标数
int point = nums[l];
while (l < r) {
// 1.如果右指针对应的数大于目标数,则右边指针左移
while (l < r && nums[r] > point) {
r--;
}
// 2.退出循环则说明右指针指向的就是小于目标数的数字
// 这时如果左指针依旧小于右指针,进行赋值操作
if (l < r) {
nums[l] = nums[r];
l++;
}
// 3.如果左指针对应的数小于目标数,则左边指针右移
while (l < r && nums[l] < point) {
l++;
}
// 4.退出循环则说明左指针指向的就是大于目标数的数字
// 这时如果左指针依旧小于右指针,进行赋值操作
if (l < r) {
nums[r] = nums[l];
r--;
}
}
// 循环外赋值
nums[l] = point;
第一个数为坑位,黄色高亮,代码1、2两步再这进行
这里坑位变成了右边那个赋值给坑位的位置了,对应3、4步
一次外循环结束了
继续执行
这时终止了
循环外赋值
因为我们每次循环可以同时整理一个小的数和一个大的数,所以肯定是快速的!
一次快排让目标数8左边的数都比8小,右边的数都比8大
我们依据分治思想,对8左边的子数组继续进行快排,右边也是一样的
最终代码
public void quickSort (int[] nums, int left, int right) {
if (left < right) {
int l = left;
int r = right;
int point = nums[l];
while (l < r) {
// 1.如果目的右边的数大于目标数,则右边指针左移
while (l < r && nums[r] > point) {
r--;
}
// 2.退出循环则说明右指针指向的就是小于目标数的数字
// 这时如果左指针依旧小于右指针,进行赋值操作
if (l < r) {
nums[l] = nums[r];
l++;
}
// 3.如果目的左边的数小于目标数,则左边指针右移
while (l < r && nums[l] < point) {
l++;
}
// 4.退出循环则说明左指针指向的就是大于目标数的数字
// 这时如果左指针依旧小于右指针,进行赋值操作
if (l < r) {
nums[r] = nums[l];
r--;
}
}
// 循环外赋值
nums[l] = point;
// 对右边数组进行快排
quickSort(nums, l + 1, right);
// 对左边数组进行快排
quickSort(nums, left, l - 1);
}
}
最终保证整个数组的有序性