个人学习记录
java实现快速排序,当然也能直接使用Arrays.sort();这个方法
代码实现
public class KuaiSuPaiXv {
private static final Random RANDOM = new Random(System.currentTimeMillis());
public static void main(String[] args) {
int[] nums = new int[]{5, 4, 1, 2, 7, 9, 8, 3, 6};
int[] ints = sortArray(nums);
for (int i = 0; i < ints.length; i++) {
System.out.println("nums = " + ints[i]);
}
}
public static int[] sortArray(int[] nums) {
quickSort(nums, 0, nums.length - 1);
return nums;
}
private static void quickSort(int[] nums, int left, int right) {
// 如果最左边的长度大于右边那就直接返回
if (left >= right) {
return;
}
// 随机下标 left在加上是给第三区间作比较的 因为第一区间始终是0
int randomIndex = left + RANDOM.nextInt(right - left + 1);
// 数据替换
swap(nums, left, randomIndex);
// 根据随机下标替换的数据为分界线
int pivot = nums[left];
// all in nums[left + 1..lt) < pivot
// all in nums[lt..i) = pivot 第二区间
// all in nums(gt..right] > pivot
// 最左边 +1 是因为 left是0 此时0下标数据是分界线数据 代表第一区间
int lt = left + 1;
// 最右边 代表第三区间
int gt = right;
// 指针
int i = left + 1;
// 当最右边的指针比当前指针还小的话,那么就三个区间分完了
while (i <= gt) {
// 如果当前这个数据比分界线数据小 那么就 就将最左边的数据跟其对换 因为要把比分界线数据小的值放到第一区间
// 再将两个指针向后走一步
if (nums[i] < pivot) {
// 有可能 最左边和当前指针是同一个下标 不同时在对换数据
if (lt != i) {
swap(nums, i, lt);
}
lt++;
i++;
// 如果数据一样 那么当前指针i继续向后走一步
} else if (nums[i] == pivot) {
i++;
} else {
// 如果比分界线的数据大 那么就和 最后边的数据对换 并且最后边的数据向前走一步
// i不动 因为此时并不明确i当前对换过来的值是否比分界线的数值大还是小
// nums[i] > pivot
swap(nums, i, gt);
gt--;
}
}
// 将最初的分界线的数据跟lt(在第一区间中最后一个数据)中最小的位置调换
swap(nums, left, lt - 1);
// 将第一区间重新调用
quickSort(nums, left, lt - 2);
// 将第三区间重新调用
quickSort(nums, gt + 1, right);
}
// 位置替换
private static void swap(int[] nums, int index1, int index2) {
int temp = nums[index1];
nums[index1] = nums[index2];
nums[index2] = temp;
}
}