-
基本原理:查找一个基准值,根据该值对数组一分为二,一边是小于等于,一边是大于;对于拆分之后的两个数组继续进行上述操作。利用了分治思想
-
需要额外空间的方法:
public class QuickSort {
public static void sort(int[] nums) {
if (nums == null || nums.length < 2) {
return;
}
doSort(nums, 0, nums.length - 1);
}
/**
* 左闭右闭区间
*
* @param nums
* @param startIdx
* @param endIdx
*/
private static void doSort(int[] nums, int startIdx, int endIdx) {
// 必须要有结束条件
if (endIdx <= startIdx) {
return;
}
// 先将根据p分开
int p = nums[endIdx];
int[] lessArray = new int[endIdx - startIdx + 1];
int[] moreArray = new int[endIdx - startIdx + 1];
int lessIdx = 0;
int moreIdx = 0;
for (int i = startIdx; i < endIdx; i++) {
if (nums[i] <= p) {
lessArray[lessIdx++] = nums[i];
} else {
moreArray[moreIdx++] = nums[i];
}
}
for (int i = 0; i < lessIdx; i++) {
nums[startIdx + i] = lessArray[i];
}
nums[startIdx + lessIdx] = p;
for (int i = 0; i < moreIdx; i++) {
nums[startIdx + lessIdx + i + 1] = moreArray[i];
}
// 再递归
doSort(nums, startIdx, startIdx + lessIdx - 1);
doSort(nums, startIdx + lessIdx + 1, endIdx);
}
}
- 通过元素交换的方法
public class QuickSort {
public static void sort(int[] nums) {
if (nums == null || nums.length < 2) {
return;
}
doSort(nums, 0, nums.length - 1);
}
/**
* 左闭右闭区间
*
* @param nums
* @param startIdx
* @param endIdx
*/
private static void doSort(int[] nums, int startIdx, int endIdx) {
// 必须要有结束条件
if (endIdx <= startIdx) {
return;
}
int p = nums[endIdx];
int slowIdx = startIdx;
int fastIdx = startIdx;
while (fastIdx <= endIdx) {
// 如果慢指针的值小于等于基准,那就不用操作。慢指针往后移动就行;
if (nums[slowIdx] <= p) {
slowIdx++;
// 为了防止快指针比满足慢指针慢,移动一下
fastIdx = Math.max(fastIdx, slowIdx);
continue;
}
// 如果到这里,情况是慢指针找到了大于基准值的,但是快指针还没找到小于等于基准值的。如果找到了,那就进里面交换
if (nums[fastIdx] <= p) {
swap(nums, fastIdx, slowIdx);
slowIdx++;
}
// 不管怎么样,快指针都往后走一步
fastIdx++;
}
doSort(nums, startIdx, slowIdx - 2);
doSort(nums, slowIdx, endIdx);
}
private static void swap(int[] nums, int n1, int n2) {
if (n1 >= nums.length || n2 >= nums.length) {
throw new RuntimeException("n1 or n2 illegal");
}
int temp = nums[n1];
nums[n1] = nums[n2];
nums[n2] = temp;
}
}