zoukankan      html  css  js  c++  java
  • Quick Sort

    简单快速排序

    选取数组第一个元素为临界值,然后将数组排序,小于临界值得都放在临界值左边,大于临界值的都放在临界值右边,然后递归知道数组完全有序.但是如果数组基本有序或者数组中重复元素较多的情况下,临界值的依然选择第一个就不是很恰当了,所以后续会有快排的优化

    /**
     * 简单快速排序--对于基本有序的数组和重复元素较多的数组时间复杂度较高,存在不足需要改进
     */
    public class QuickSort {
        private QuickSort() {
        }
    
        //通过分区,返回两个区的临界值
        private static <T extends Comparable<? super T>> int partition(T[] arr, int low, int high) {
            T temp = arr[low];
            int j = low;
            for (int i = low + 1; i <= high; i++) {
                if (arr[i].compareTo(temp) < 0) {
                    j++;
                    swap(arr, i, j);
                }
            }
            swap(arr, low, j);
            return j;
        }
    
        //递归将数组分区
        private static <T extends Comparable<? super T>> void sort(T[] arr, int low, int high) {
            if (low >= high) {
                return;
            }
            int partition = partition(arr, low, high);
            sort(arr, low, partition - 1);
            sort(arr, partition + 1, high);
        }
    
        public static <T extends Comparable<? super T>> void sort(T[] arr) {
            sort(arr, 0, arr.length - 1);
        }
    
        //交换数组中的两个元素
        private static <T extends Comparable<? super T>> void swap(T[] arr, int i, int j) {
            T temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    
        //打印数组元素
        public static <T extends Comparable<? super T>> void printArray(T[] arr) {
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        }
    
        public static void main(String[] args) {
            Integer[] arr = {9, 5, 1, 3, 7, 2, 8, 4, 6, 10};
            sort(arr);
            printArray(arr);
        }
    }  

    快速排序优化

    优化一:如果基本有序数组的第一个元素是临界值,那么临界值很可能是最小的元素,导致分区不均,时间复杂度相当于O(n^2),所以为了尽量消除数组基本有序的情况,在数组中随机选取一个元素,解决了数组基本有序排序效率低的情况,但是若数组中存在大量重复元素,效率低的情况仍未解决.

    优化二:对于数组中元素基本有序时,可以更换为直接插入排序,提高排序效率

    public class QuickSort {
        private QuickSort() {
        }
    
        //通过分区,返回两个区的临界值
        private static <T extends Comparable<? super T>> int partition(T[] arr, int low, int high) {
            /*优化一:随机选取数组中的一个元素,将其与数组第一个元素进行交换*/
            swap(arr, low, (int) (Math.random() * (high - low + 1) + low));
            T temp = arr[low];
            int j = low;
            for (int i = low + 1; i <= high; i++) {
                if (arr[i].compareTo(temp) < 0) {
                    j++;
                    swap(arr, i, j);
                }
            }
            swap(arr, low, j);
            return j;
        }
    
        //递归将数组分区
        private static <T extends Comparable<? super T>> void sort(T[] arr, int low, int high) {
            /*优化二:对于基本有序的数组可以使用直接插入排序*/
            if (high - low <= 15) {
                insertionSort(arr, low, high);
                return;
            }
            int partition = partition(arr, low, high);
            sort(arr, low, partition - 1);
            sort(arr, partition + 1, high);
        }
    
        public static <T extends Comparable<? super T>> void sort(T[] arr) {
            sort(arr, 0, arr.length - 1);
        }
    
        // 对arr[l...r]的区间使用InsertionSort排序
        public static void insertionSort(Comparable[] arr, int l, int r) {
    
            for (int i = l + 1; i <= r; i++) {
                Comparable temp = arr[i];
                int j = i;
                for (; j > l && arr[j - 1].compareTo(temp) > 0; j--)
                    arr[j] = arr[j - 1];
                arr[j] = temp;
            }
        }
    
        //交换数组中的两个元素
        private static <T extends Comparable<? super T>> void swap(T[] arr, int i, int j) {
            T temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    
        //打印数组元素
        public static <T extends Comparable<? super T>> void printArray(T[] arr) {
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        }
    
        public static void main(String[] args) {
            Integer[] arr = {9, 5, 1, 3, 7, 2, 8, 4, 6, 10};
            sort(arr);
            printArray(arr);
        }
    }  

     快速排序--优化2

    从左向右找比临界值大的,从右向左找比临界值小的,然后将两者交换,这样对于大量相同的元素不用全部交换,解决了数组中存在大量元素的问题

    public class QuickSort {
        private QuickSort() {
        }
    
        //通过分区,返回两个区的临界值
        private static <T extends Comparable<? super T>> int partition(T[] arr, int low, int high) {
            /*优化:随机选取数组中的一个元素,将其与数组第一个元素进行交换*/
            swap(arr, low, (int) (Math.random() * (high - low + 1) + low));
            T temp = arr[low];
            int i = low + 1;
            int j = high;
            while (true) {
                while (i <= high && arr[i].compareTo(temp) < 0) {
                    i++;
                }
                while (j >= low + 1 && arr[j].compareTo(temp) > 0) {
                    j--;
                }
                if (i > j) {
                    break;
                }
                swap(arr,i,j);
                i++;
                j--;
            }
            swap(arr, low, j);
            return j;
        }
    
        //递归将数组分区
        private static <T extends Comparable<? super T>> void sort(T[] arr, int low, int high) {
            /*对于基本有序的数组可以使用直接插入排序*/
            if (high - low <= 15) {
                insertionSort(arr, low, high);
                return;
            }
            int partition = partition(arr, low, high);
            sort(arr, low, partition - 1);
            sort(arr, partition + 1, high);
        }
    
        public static <T extends Comparable<? super T>> void sort(T[] arr) {
            sort(arr, 0, arr.length - 1);
        }
    
        // 对arr[l...r]的区间使用InsertionSort排序
        public static void insertionSort(Comparable[] arr, int l, int r) {
    
            for (int i = l + 1; i <= r; i++) {
                Comparable temp = arr[i];
                int j = i;
                for (; j > l && arr[j - 1].compareTo(temp) > 0; j--)
                    arr[j] = arr[j - 1];
                arr[j] = temp;
            }
        }
    
        //交换数组中的两个元素
        private static <T extends Comparable<? super T>> void swap(T[] arr, int i, int j) {
            T temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    
        //打印数组元素
        public static <T extends Comparable<? super T>> void printArray(T[] arr) {
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        }
    
        public static void main(String[] args) {
            Integer[] arr = {9, 5, 1, 3,7, 7, 2, 8, 4, 6, 10};
            sort(arr);
            printArray(arr);
        }
    }
    

    两路快排--不交换 

    public class QuickSort {
        private QuickSort() {
        }
    
        //通过分区,返回两个区的临界值
        private static <T extends Comparable<? super T>> int partition(T[] arr, int low, int high) {
            /*优化:随机选取数组中的一个元素,将其与数组第一个元素进行交换*/
            swap(arr, low, (int) (Math.random() * (high - low + 1) + low));
            T temp = arr[low];
            int i = low + 1;
            int j = high;
            while (i < j) {
                while (i < j && temp.compareTo(arr[j]) < 0) {
                    j--;
                }
                arr[i] = arr[j]; //j停在那里不动
                while (i < j && temp.compareTo(arr[j]) > 0) {
                    i++;
                }
                arr[j] = arr[i];//i停在那里不动
            }
            arr[j] = temp;
            return j;
        }
    
        //递归将数组分区
        private static <T extends Comparable<? super T>> void sort(T[] arr, int low, int high) {
            /*对于基本有序的数组可以使用直接插入排序*/
            if (high - low <= 15) {
                insertionSort(arr, low, high);
                return;
            }
            int partition = partition(arr, low, high);
            sort(arr, low, partition - 1);
            sort(arr, partition + 1, high);
        }
    
        public static <T extends Comparable<? super T>> void sort(T[] arr) {
            sort(arr, 0, arr.length - 1);
        }
    
        // 对arr[l...r]的区间使用InsertionSort排序
        public static void insertionSort(Comparable[] arr, int l, int r) {
    
            for (int i = l + 1; i <= r; i++) {
                Comparable temp = arr[i];
                int j = i;
                for (; j > l && arr[j - 1].compareTo(temp) > 0; j--)
                    arr[j] = arr[j - 1];
                arr[j] = temp;
            }
        }
    
        //交换数组中的两个元素
        private static <T extends Comparable<? super T>> void swap(T[] arr, int i, int j) {
            T temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    
        //打印数组元素
        public static <T extends Comparable<? super T>> void printArray(T[] arr) {
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        }
    
        public static void main(String[] args) {
            Integer[] arr = {9, 5, 1, 3, 7, 7, 2, 8, 4, 6, 10};
            sort(arr);
            printArray(arr);
        }
    }  

    三路快排

    public class QuickSort {
        private QuickSort() {
        }
    
        private static <T extends Comparable<? super T>> int[] partition(T[] arr, int low, int high) {
            swap(arr, low, (int) (Math.random() * (high - low + 1) + low));
            T temp = arr[low];
            int i = low;
            int j = high;
            int cur = i;
            while (cur <= j) {
                if (temp.compareTo(arr[cur]) == 0) {
                    cur++;
                } else if (temp.compareTo(arr[cur]) > 0) {
                    swap(arr, cur++, i++);
                } else {
                    swap(arr, cur, j--);
                }
            }
            return new int[]{i - 1, j + 1};
        }
    
        private static <T extends Comparable<? super T>> void sort(T[] arr, int low, int high) {
            if (high - low <= 15) {
                insertionSort(arr, low, high);
                return;
            }
    
            int[] ret = partition(arr, low, high);
            sort(arr, low, ret[0]);
            sort(arr, ret[1], high);
        }
    
        public static <T extends Comparable<? super T>> void sort(T[] arr) {
            sort(arr, 0, arr.length - 1);
        }
    
        // 对arr[l...r]的区间使用InsertionSort排序
        private static void insertionSort(Comparable[] arr, int l, int r) {
    
            for (int i = l + 1; i <= r; i++) {
                Comparable temp = arr[i];
                int j = i;
                for (; j > l && arr[j - 1].compareTo(temp) > 0; j--)
                    arr[j] = arr[j - 1];
                arr[j] = temp;
            }
        }
    
        //交换数组中的两个元素
        private static <T extends Comparable<? super T>> void swap(T[] arr, int i, int j) {
            T temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    
        //打印数组元素
        public static <T extends Comparable<? super T>> void printArray(T[] arr) {
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        }
    
        public static void main(String[] args) {
            Integer[] arr = {9, 5, 1, 3, 7, 7, 2, 8, 4, 6, 10};
            sort(arr);
            printArray(arr);
        }
    }
    

      

  • 相关阅读:
    分页,上传,下载
    java web 开发模式
    EL/JSTL-jsp页面更简单的输出方式
    过滤器和监听器
    Servlet
    jsp标准动作
    java Bean
    寻找你的热情(1)——检查自己所处的位置
    fedora25 安装sublime text3
    python实例3-天气小模块
  • 原文地址:https://www.cnblogs.com/Hangtutu/p/8023536.html
Copyright © 2011-2022 走看看