快速排序(QuickSort)
它采用了一种分治的策略,通常称其为分治法
通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
步骤:
- 确认一下基准值(最左边的)
- 左右指针,分边找出比基准值大(
left
)、小(right
)的两个值(右边开始找) - 互换两个值
- 循环2.3步骤,直到左右指针相遇
- 基准值跟指针所在的值互换位置
- 以基准值为界,分开左右两个区间,重新开始步骤1
如图所示:
快速排序的时间复杂度为:O(NlogN)
最坏情况是:O(n^2)
空间复杂度 最好情况是O(logn),最坏情况也就是O(n)
下面上代码:
public static void main(String[] args) {
int[] nums = new int[]{1, 2, 1, 2, 2, 2, 1, 2, 1, 2, 1};
int left = 0;
int right = nums.length - 1;
quickSort(nums, left, right);
for (int i = 0; i < nums.length; i++) {
System.out.println(nums[i]);
}
}
private static void quickSort(int[] nums, int left, int right) {
if (left > right) return;
int num = nums[left];
int i = left;
int j = right;
while (left < right) {
// 为什么先从右边开始?
// 因为左边先停,只有两个情况:①比基数大或者②left=right
// ①情况,假如right也停在该值上,左右区间就不会出现一边大一边小情况
while (nums[right] >= num && left < right) {
right--;
}
while (nums[left] <= num && left < right) {
left++;
}
if (left < right) {
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
}
}
// 基数放至中间
nums[i] = nums[left];
nums[left] = num;
// left==right 基数就是num
// 减一加一,区间范围减少,不然会进入死循环
quickSort(nums, i, left-1);
quickSort(nums, left+1, j);
}