zoukankan      html  css  js  c++  java
  • 快速排序


    import java.util.Arrays;

    /**
    * 快速排序
    * <p>
    * 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,
    * 然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列
    */
    public class QuickSort {

    public static void main(String[] args) {
    // 测试次数
    int times = 50000;

    int maxNum = 100;
    int maxSize = 100;
    for (int i = 0; i < times; i++) {
    // 生成随机数组
    int[] arr1 = generateArray(maxNum, maxSize);
    // 复制
    int[] arr2 = copyArray(arr1);
    // 排序
    quickSort1(arr1);
    // quickSort2(arr1);
    // quickSort3(arr1);
    // Api排序
    Arrays.sort(arr2);
    // 比较排序结果
    if (!arrayEquals(arr1, arr2)) {
    System.out.println("Sort failed!!!");
    System.out.println(Arrays.toString(arr1));
    System.out.println(Arrays.toString(arr2));
    return;
    }
    }
    System.out.println("Sort success");
    }

    /**
    * 快排第一种实现方式
    * 每次分两组: <= 和 >
    *
    * @param arr 数组
    */
    public static void quickSort1(int[] arr) {
    if (arr == null || arr.length < 2) {
    return;
    }
    process1(arr, 0, arr.length - 1);
    }

    public static void process1(int[] arr, int left, int right) {
    if (left >= right) {
    return;
    }
    int mid = patition(arr, left, right);
    process1(arr, left, mid - 1);
    process1(arr, mid + 1, right);
    }

    public static int patition(int[] arr, int left, int right) {
    if (arr == null || arr.length < 2) {
    return 0;
    }
    int index = left - 1;
    for (int i = left; i <= right; i++) {
    if (arr[i] <= arr[right]) {
    swap(arr, i, ++index);
    }
    }
    return index;
    }

    /**
    * 快排第二种实现方式
    * 每次分三组: < 和 = 和 >
    *
    * @param arr 数组
    */
    public static void quickSort2(int[] arr) {
    if (arr == null || arr.length < 2) {
    return;
    }
    process2(arr, 0, arr.length - 1);
    }

    public static void process2(int[] arr, int left, int right) {
    if (left >= right) {
    return;
    }
    int[] index = netherlandFlag(arr, left, right);
    process2(arr, left, index[0] - 1);
    process2(arr, index[1] + 1, right);
    }

    /**
    * 荷兰国旗划分 以arr[right] 为划分值
    *
    * @param arr 数组
    * @param left 左边界
    * @param right 右边界
    * @return 等于区域的下标范围
    */
    public static int[] netherlandFlag(int[] arr, int left, int right) {
    if (left > right) {
    return new int[]{-1, -1};
    }
    if (left == right) {
    return new int[]{left, right};
    }
    int less = left - 1;
    int more = right;
    int index = left;
    while (index < more) {
    if (arr[index] < arr[right]) {
    swap(arr, index++, ++less);
    } else if (arr[index] > arr[right]) {
    swap(arr, index, --more);
    } else {
    index++;
    }
    }
    swap(arr, more, right);
    return new int[]{less + 1, more};
    }

    /**
    * 快排第三种实现方式
    * 在第二种实现方式的基础上,每次随机挑选一个划分值
    *
    * @param arr 数组
    */
    public static void quickSort3(int[] arr) {
    if (arr == null || arr.length < 2) {
    return;
    }
    process3(arr, 0, arr.length - 1);
    }

    public static void process3(int[] arr, int left, int right) {
    if (left >= right) {
    return;
    }
    int[] index = netherlandFlag2(arr, left, right);
    process3(arr, left, index[0] - 1);
    process3(arr, index[1] + 1, right);
    }

    /**
    * 荷兰国旗划分 以arr[right] 为划分值
    *
    * @param arr 数组
    * @param left 左边界
    * @param right 右边界
    * @return 等于区域的下标范围
    */
    public static int[] netherlandFlag2(int[] arr, int left, int right) {
    if (left > right) {
    return new int[]{-1, -1};
    }
    if (left == right) {
    return new int[]{left, right};
    }
    //随机挑选一个划分值
    int radom = left + ((int) (Math.random() * (right - left)));
    swap(arr, radom, right);

    int less = left - 1;
    int more = right;
    int index = left;
    while (index < more) {
    if (arr[index] < arr[right]) {
    swap(arr, index++, ++less);
    } else if (arr[index] > arr[right]) {
    swap(arr, index, --more);
    } else {
    index++;
    }
    }
    swap(arr, more, right);
    return new int[]{less + 1, more};
    }

    /**
    * 交换数组两个元素的位置
    *
    * @param arr 数组
    * @param i 位置
    * @param j 位置
    */
    private static void swap(int[] arr, int i, int j) {
    // 同一个位置交换无意义,并且用异或交换会有问题
    if (i == j) {
    return;
    }
    // 交换
    arr[i] = arr[i] ^ arr[j];
    arr[j] = arr[i] ^ arr[j];
    arr[i] = arr[i] ^ arr[j];
    }

    /**
    * 生成随机数组
    *
    * @param maxNum 最大数
    * @param maxSize 数组最大大小
    * @return 随机数组
    */
    private static int[] generateArray(int maxNum, int maxSize) {
    int[] arr = new int[(int) (maxSize * Math.random())];
    for (int i = 0; i < arr.length; i++) {
    arr[i] = (int) (maxNum * Math.random()) - (int) (maxNum * Math.random());
    }
    return arr;
    }

    /**
    * 判断两数组是否完全相同
    *
    * @param arr1 数组1
    * @param arr2 数组2
    * @return 是否相同
    */
    private static boolean arrayEquals(int[] arr1, int[] arr2) {
    if (arr1 == arr2) {
    return true;
    }
    if (arr1 == null || arr2 == null || arr1.length != arr2.length) {
    return false;
    }
    for (int i = 0; i < arr1.length; i++) {
    if (arr1[i] != arr2[i]) {
    return false;
    }
    }
    return true;
    }

    /**
    * 复制数组
    *
    * @param arr 要复制的数组
    * @return 复制的数组
    */
    private static int[] copyArray(int[] arr) {
    if (arr == null) {
    return null;
    }
    int[] copy = new int[arr.length];
    for (int i = 0; i < arr.length; i++) {
    copy[i] = arr[i];
    }
    return copy;
    }

    }

    /* 如有错误,欢迎批评指正 */
  • 相关阅读:
    7行代码看EntityFramework是如何运行
    我用ASP.NET缓存之SQL数据缓存依赖(SqlCacheDependency)
    利用Microsoft.Office.Interop.Excel 将web页面转成PDF
    IT农民的开发人员工具清单(2013年)
    我在项目中运用 IOC(依赖注入)--实战篇
    我在项目中运用 IOC(依赖注入)--入门篇
    我用ASP.NET缓存之数据缓存
    我用ASP.NET缓存之OutputCache
    Resharper 使用帮助-自动生成文件头
    玩转变量、环境变量以及数学运算(shell)
  • 原文地址:https://www.cnblogs.com/laydown/p/12814805.html
Copyright © 2011-2022 走看看