package com.wzy.train;
import java.util.Arrays;
import java.util.Random;
/**
* @Author: wzy
* @Description:
* @Date: 2019/12/12 10:20
*/
public class Main {
private static Random random = new Random();
public static void main(String[] args) {
int[] a = new int[]{6, 6, 6, 6, 6, 9, 12, 5, 2, 0, 8, 5, 3, 2};
quickSort(a, 0, a.length - 1);
System.out.println(Arrays.toString(a));
}
private static void quickSort(int[] a, int start, int end) {
if (start >= end) {
return;
}
int index = partition3(a, start, end);
if (index > start + 1) {
quickSort(a, start, index - 1);
}
if (index < end - 1) {
quickSort(a, index + 1, end);
}
}
/**
* 1、选择排序的思想,将小于prvot的元素逐一选择到前面
* @param nums 数组
* @param left 左指针
* @param right 右指针
* @return pivot下标
*/
private static int partition1(int[] nums, int left, int right) {
// 这里采用随机取数的方式,降低最坏情况(即时间复杂度退化为O(n2))的几率
random(nums, left, right);
int pivot = nums[left];
int j = left;
// 注意下标是从left+1开始,不是left
for (int i = left + 1; i <= right; i++) {
// 小于 pivot 的元素都被交换到前面
if (nums[i] < pivot) {
j++;
swap(nums, j, i);
}
}
// 在之前遍历的过程中,满足 [left + 1, j] < pivot,并且 (j, i] >= pivot
swap(nums, j, left);
// 交换以后 [left, j - 1] < pivot, nums[j] = pivot, [j + 1, right] >= pivot
return j;
}
/**
* 2、双指针写法,直接交换
* @param nums 数组
* @param left 左指针
* @param right 右指针
* @return pivot下标
*/
private static int partition2(int[] nums, int left, int right) {
random(nums, left, right);
int key = nums[left];
while (right > left) {
//从后往前比较
while (right > left && nums[right] >= key) right--;
if (nums[right] <= key) {
swap(nums, left, right);
}
//从前往后比较
while (right > left && nums[left] <= key) left++;
if (nums[left] >= key) {
swap(nums, left, right);
}
}
return left;
}
/**
* 3、双指针写法,使用哨兵,减少交换
* @param nums 数组
* @param left 左指针
* @param right 右指针
* @return pivot下标
*/
private static int partition3(int[] nums, int left, int right) {
// 这里采用随机取数的方式,降低最坏情况(即时间复杂度退化为O(n2))的几率。
random(nums, left, right);
int pivot = nums[left];
while (right > left) {
while (right > left && nums[right] >= pivot) right--;
nums[left] = nums[right];
while (right > left && nums[left] < pivot) left++;
nums[right] = nums[left];
}
// 归还privot到分割点
nums[left] = pivot;
return left;
}
private static void random(int[] nums, int left, int right) {
if (right > left) {
int randomIndex = left + 1 + random.nextInt(right - left);
swap(nums, left, randomIndex);
}
}
private static void swap(int[] nums, int a, int b) {
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}
}
快速排序的几种写法[Java]
最新推荐文章于 2023-10-02 13:41:43 发布