zoukankan      html  css  js  c++  java
  • 算法设计与分析——排序

    关于排序的原文网址:https://algs4.cs.princeton.edu/21elementary/

    选择排序(Selection sort)

    思想

    1. 遍历数组,设置最小值的索引为 0,
    2. 如果取出的值比当前最小值小,就替换最小值索引,遍历完成后,将第一个元素和最小值索引上的值交换。
    3. 如上操作后,第一个元素就是数组中的最小值,下次遍历就可以从索引 1 开始重复上述操作。
    package sort;
    import java.util.Comparator;
    
    public class Selection {
    
        // This class should not be instantiated.
        private Selection() { }
    
        /**
         * Rearranges the array in ascending order, using the natural order.
         * @param a the array to be sorted
         */
        public static void sort(Comparable[] a) {
            int n = a.length;
            for (int i = 0; i < n; i++) {
                int min = i;
                for (int j = i+1; j < n; j++) {
                    if (less(a[j], a[min])) min = j;
                }
                exch(a, i, min);
                assert isSorted(a, 0, i);
            }
            assert isSorted(a);
        }
    
        /**
         * Rearranges the array in ascending order, using a comparator.
         * @param a the array
         * @param comparator the comparator specifying the order
         */
        public static void sort(Object[] a, Comparator comparator) {
            int n = a.length;
            for (int i = 0; i < n; i++) {
                int min = i;
                for (int j = i+1; j < n; j++) {
                    if (less(comparator, a[j], a[min])) min = j;
                }
                exch(a, i, min);
                assert isSorted(a, comparator, 0, i);
            }
            assert isSorted(a, comparator);
        }
    
    
       /***************************************************************************
        *  Helper sorting functions.
        ***************************************************************************/
        
        // is v < w ?
        private static boolean less(Comparable v, Comparable w) {
            return v.compareTo(w) < 0;
        }
    
        // is v < w ?
        private static boolean less(Comparator comparator, Object v, Object w) {
            return comparator.compare(v, w) < 0;
        }
            
            
        // exchange a[i] and a[j]
        private static void exch(Object[] a, int i, int j) {
            Object swap = a[i];
            a[i] = a[j];
            a[j] = swap;
        }
    
    
       /***************************************************************************
        *  Check if array is sorted - useful for debugging.
        ***************************************************************************/
    
        // is the array a[] sorted?
        private static boolean isSorted(Comparable[] a) {
            return isSorted(a, 0, a.length - 1);
        }
            
        // is the array sorted from a[lo] to a[hi]
        private static boolean isSorted(Comparable[] a, int lo, int hi) {
            for (int i = lo + 1; i <= hi; i++)
                if (less(a[i], a[i-1])) return false;
            return true;
        }
    
        // is the array a[] sorted?
        private static boolean isSorted(Object[] a, Comparator comparator) {
            return isSorted(a, comparator, 0, a.length - 1);
        }
    
        // is the array sorted from a[lo] to a[hi]
        private static boolean isSorted(Object[] a, Comparator comparator, int lo, int hi) {
            for (int i = lo + 1; i <= hi; i++)
                if (less(comparator, a[i], a[i-1])) return false;
            return true;
        }
    
    
    
        // print array to standard output
        private static void show(Comparable[] a) {
            for (int i = 0; i < a.length; i++) {
            	System.out.println(a[i]);
            }
        }
    
        /**
         * Reads in a sequence of strings from standard input; selection sorts them; 
         * and prints them to standard output in ascending order. 
         *
         * @param args the command-line arguments
         */
        public static void main(String[] args) {
        	Integer a[] = new Integer[]{40,20,12,70};
            Selection.sort(a);
            show(a);
        }
    }
    

    运行结果

              

    插入排序(Insertion sort)

    思想:

    1. 从第一个元素开始,该元素可以认为已经被排序;
    2. 取出当前元素的后一个元素,在已经排序的元素序列中从后向前循环一遍;
    3. 如果该元素(已排序的元素)大于新元素,将该元素移到下一位置;
    4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
    5. 将新元素插入到该位置后;
    6. 重复步骤2~5。
    package sort;
    import java.util.Comparator;
    
    public class Insertion {
    
        // This class should not be instantiated.
        private Insertion() { }
    
        /**
         * Rearranges the array in ascending order, using the natural order.
         * @param a the array to be sorted
         */
        public static void sort(Comparable[] a) {
            int n = a.length;
            for (int i = 1; i < n; i++) {
                for (int j = i; j > 0 && less(a[j], a[j-1]); j--) {
                    exch(a, j, j-1);
                }
                assert isSorted(a, 0, i);
            }
            assert isSorted(a);
        }
    
        /**
         * Rearranges the subarray a[lo..hi) in ascending order, using the natural order.
         * @param a the array to be sorted
         * @param lo left endpoint (inclusive)
         * @param hi right endpoint (exclusive)
         */
        public static void sort(Comparable[] a, int lo, int hi) {
            for (int i = lo + 1; i < hi; i++) {
                for (int j = i; j > lo && less(a[j], a[j-1]); j--) {
                    exch(a, j, j-1);
                }
            }
            assert isSorted(a, lo, hi);
        }
    
        /**
         * Rearranges the array in ascending order, using a comparator.
         * @param a the array
         * @param comparator the comparator specifying the order
         */
        public static void sort(Object[] a, Comparator comparator) {
            int n = a.length;
            for (int i = 1; i < n; i++) {
                for (int j = i; j > 0 && less(a[j], a[j-1], comparator); j--) {
                    exch(a, j, j-1);
                }
                assert isSorted(a, 0, i, comparator);
            }
            assert isSorted(a, comparator);
        }
    
        /**
         * Rearranges the subarray a[lo..hi) in ascending order, using a comparator.
         * @param a the array
         * @param lo left endpoint (inclusive)
         * @param hi right endpoint (exclusive)
         * @param comparator the comparator specifying the order
         */
        public static void sort(Object[] a, int lo, int hi, Comparator comparator) {
            for (int i = lo + 1; i < hi; i++) {
                for (int j = i; j > lo && less(a[j], a[j-1], comparator); j--) {
                    exch(a, j, j-1);
                }
            }
            assert isSorted(a, lo, hi, comparator);
        }
    
    
        // return a permutation that gives the elements in a[] in ascending order
        // do not change the original array a[]
        /**
         * Returns a permutation that gives the elements in the array in ascending order.
         * @param a the array
         * @return a permutation {@code p[]} such that {@code a[p[0]]}, {@code a[p[1]]},
         *    ..., {@code a[p[n-1]]} are in ascending order
         */
        public static int[] indexSort(Comparable[] a) {
            int n = a.length;
            int[] index = new int[n];
            for (int i = 0; i < n; i++)
                index[i] = i;
    
            for (int i = 1; i < n; i++)
                for (int j = i; j > 0 && less(a[index[j]], a[index[j-1]]); j--)
                    exch(index, j, j-1);
    
            return index;
        }
    
       /***************************************************************************
        *  Helper sorting functions.
        ***************************************************************************/
        
        // is v < w ?
        private static boolean less(Comparable v, Comparable w) {
            return v.compareTo(w) < 0;
        }
    
        // is v < w ?
        private static boolean less(Object v, Object w, Comparator comparator) {
            return comparator.compare(v, w) < 0;
        }
            
        // exchange a[i] and a[j]
        private static void exch(Object[] a, int i, int j) {
            Object swap = a[i];
            a[i] = a[j];
            a[j] = swap;
        }
    
        // exchange a[i] and a[j]  (for indirect sort)
        private static void exch(int[] a, int i, int j) {
            int swap = a[i];
            a[i] = a[j];
            a[j] = swap;
        }
    
       /***************************************************************************
        *  Check if array is sorted - useful for debugging.
        ***************************************************************************/
        private static boolean isSorted(Comparable[] a) {
            return isSorted(a, 0, a.length);
        }
    
        // is the array a[lo..hi) sorted
        private static boolean isSorted(Comparable[] a, int lo, int hi) {
            for (int i = lo + 1; i < hi; i++)
                if (less(a[i], a[i-1])) return false;
            return true;
        }
    
        private static boolean isSorted(Object[] a, Comparator comparator) {
            return isSorted(a, 0, a.length, comparator);
        }
    
        // is the array a[lo..hi) sorted
        private static boolean isSorted(Object[] a, int lo, int hi, Comparator comparator) {
            for (int i = lo + 1; i < hi; i++)
                if (less(a[i], a[i-1], comparator)) return false;
            return true;
        }
    
       // print array to standard output
        private static void show(Comparable[] a) {
            for (int i = 0; i < a.length; i++) {
            	System.out.println(a[i]);
            }
        }
    
        /**
         * Reads in a sequence of strings from standard input; insertion sorts them;
         * and prints them to standard output in ascending order.
         *
         * @param args the command-line arguments
         */
        public static void main(String[] args) {
        	Integer a[] = new Integer[]{80,12,4,95,7};
            Insertion.sort(a);
            show(a);
        }
    }
    

    运行结果

              

    希尔排序(Shellsort)

    思想

    1. 设待排序元素序列有n个元素,首先取一个整数increment(小于n)作为间隔将全部元素分为increment个子序列,所有距离为increment的元素放在同一个子序列中。
    2. 在每一个子序列中分别实行直接插入排序。
    3. 然后缩小间隔increment
    4. 重复上述子序列划分和排序工作。
    5. 直到最后取increment=1,将所有元素放在同一个子序列中排序为止。
    package sort;
    
    public class Shell {
    
        // This class should not be instantiated.
        private Shell() { }
    
        /**
         * Rearranges the array in ascending order, using the natural order.
         * @param a the array to be sorted
         */
        public static void sort(Comparable[] a) {
            int n = a.length;
    
            // 3x+1 increment sequence:  1, 4, 13, 40, 121, 364, 1093, ... 
            int h = 1;
            while (h < n/3) h = 3*h + 1; 
    
            while (h >= 1) {
                // h-sort the array
                for (int i = h; i < n; i++) {
                    for (int j = i; j >= h && less(a[j], a[j-h]); j -= h) {
                        exch(a, j, j-h);
                    }
                }
                assert isHsorted(a, h); 
                h /= 3;
            }
            assert isSorted(a);
        }
    
    
    
       /***************************************************************************
        *  Helper sorting functions.
        ***************************************************************************/
        
        // is v < w ?
        private static boolean less(Comparable v, Comparable w) {
            return v.compareTo(w) < 0;
        }
            
        // exchange a[i] and a[j]
        private static void exch(Object[] a, int i, int j) {
            Object swap = a[i];
            a[i] = a[j];
            a[j] = swap;
        }
    
    
       /***************************************************************************
        *  Check if array is sorted - useful for debugging.
        ***************************************************************************/
        private static boolean isSorted(Comparable[] a) {
            for (int i = 1; i < a.length; i++)
                if (less(a[i], a[i-1])) return false;
            return true;
        }
    
        // is the array h-sorted?
        private static boolean isHsorted(Comparable[] a, int h) {
            for (int i = h; i < a.length; i++)
                if (less(a[i], a[i-h])) return false;
            return true;
        }
    
        // print array to standard output
        private static void show(Comparable[] a) {
            for (int i = 0; i < a.length; i++) {
                System.out.println(a[i]);
            }
        }
    
        /**
         * Reads in a sequence of strings from standard input; Shellsorts them; 
         * and prints them to standard output in ascending order. 
         *
         * @param args the command-line arguments
         */
        public static void main(String[] args) {
            Integer a[] = new Integer[]{40,50,12,70,6};
            Shell.sort(a);
            show(a);
        }
    
    }
    

    运行结果

              

    归并排序(Mergesort)

    思想

    1. 将待排序序列从中间一分为二,对左右两边再进行递归分割操作,得到n个相互独立的子序列;
    2. 对n个独立的子序列递归的执行合并操作,最终得到有序的序列。
    package sort;
    import java.util.Comparator;
    
    public class Merge {
    
        // This class should not be instantiated.
        private Merge() { }
    
        // stably merge a[lo .. mid] with a[mid+1 ..hi] using aux[lo .. hi]
        private static void merge(Comparable[] a, Comparable[] aux, int lo, int mid, int hi) {
            // precondition: a[lo .. mid] and a[mid+1 .. hi] are sorted subarrays
            assert isSorted(a, lo, mid);
            assert isSorted(a, mid+1, hi);
    
            // copy to aux[]
            for (int k = lo; k <= hi; k++) {
                aux[k] = a[k]; 
            }
    
            // merge back to a[]
            int i = lo, j = mid+1;
            for (int k = lo; k <= hi; k++) {
                if      (i > mid)              a[k] = aux[j++];
                else if (j > hi)               a[k] = aux[i++];
                else if (less(aux[j], aux[i])) a[k] = aux[j++];
                else                           a[k] = aux[i++];
            }
    
            // postcondition: a[lo .. hi] is sorted
            assert isSorted(a, lo, hi);
        }
    
        // mergesort a[lo..hi] using auxiliary array aux[lo..hi]
        private static void sort(Comparable[] a, Comparable[] aux, int lo, int hi) {
            if (hi <= lo) return;
            int mid = lo + (hi - lo) / 2;
            sort(a, aux, lo, mid);
            sort(a, aux, mid + 1, hi);
            merge(a, aux, lo, mid, hi);
        }
    
        /**
         * Rearranges the array in ascending order, using the natural order.
         * @param a the array to be sorted
         */
        public static void sort(Comparable[] a) {
            Comparable[] aux = new Comparable[a.length];
            sort(a, aux, 0, a.length-1);
            assert isSorted(a);
        }
    
    
       /***************************************************************************
        *  Helper sorting function.
        ***************************************************************************/
        
        // is v < w ?
        private static boolean less(Comparable v, Comparable w) {
            return v.compareTo(w) < 0;
        }
            
       /***************************************************************************
        *  Check if array is sorted - useful for debugging.
        ***************************************************************************/
        private static boolean isSorted(Comparable[] a) {
            return isSorted(a, 0, a.length - 1);
        }
    
        private static boolean isSorted(Comparable[] a, int lo, int hi) {
            for (int i = lo + 1; i <= hi; i++)
                if (less(a[i], a[i-1])) return false;
            return true;
        }
    
    
       /***************************************************************************
        *  Index mergesort.
        ***************************************************************************/
        // stably merge a[lo .. mid] with a[mid+1 .. hi] using aux[lo .. hi]
        private static void merge(Comparable[] a, int[] index, int[] aux, int lo, int mid, int hi) {
    
            // copy to aux[]
            for (int k = lo; k <= hi; k++) {
                aux[k] = index[k]; 
            }
    
            // merge back to a[]
            int i = lo, j = mid+1;
            for (int k = lo; k <= hi; k++) {
                if      (i > mid)                    index[k] = aux[j++];
                else if (j > hi)                     index[k] = aux[i++];
                else if (less(a[aux[j]], a[aux[i]])) index[k] = aux[j++];
                else                                 index[k] = aux[i++];
            }
        }
    
        /**
         * Returns a permutation that gives the elements in the array in ascending order.
         * @param a the array
         * @return a permutation {@code p[]} such that {@code a[p[0]]}, {@code a[p[1]]},
         *    ..., {@code a[p[N-1]]} are in ascending order
         */
        public static int[] indexSort(Comparable[] a) {
            int n = a.length;
            int[] index = new int[n];
            for (int i = 0; i < n; i++)
                index[i] = i;
    
            int[] aux = new int[n];
            sort(a, index, aux, 0, n-1);
            return index;
        }
    
        // mergesort a[lo..hi] using auxiliary array aux[lo..hi]
        private static void sort(Comparable[] a, int[] index, int[] aux, int lo, int hi) {
            if (hi <= lo) return;
            int mid = lo + (hi - lo) / 2;
            sort(a, index, aux, lo, mid);
            sort(a, index, aux, mid + 1, hi);
            merge(a, index, aux, lo, mid, hi);
        }
    
        // print array to standard output
        private static void show(Comparable[] a) {
            for (int i = 0; i < a.length; i++) {
            	System.out.println(a[i]);
            }
        }
    
        /**
         * Reads in a sequence of strings from standard input; mergesorts them; 
         * and prints them to standard output in ascending order. 
         *
         * @param args the command-line arguments
         */
        public static void main(String[] args) {
        	Integer a[] = new Integer[]{4,80,30,7};
            Merge.sort(a);
            show(a);
        }
    }
    

    运行结果

              

    过程树状图

    动态演示图

  • 相关阅读:
    2491 玉蟾宫
    1704 卡片游戏
    1020 孪生蜘蛛
    1215 迷宫
    3149 爱改名的小融 2
    1316 文化之旅 2012年NOIP全国联赛普及组
    1664 清凉冷水
    157. [USACO Nov07] 奶牛跨栏
    [SCOI2005]繁忙的都市
    【NOIP2014模拟赛No.1】我要的幸福
  • 原文地址:https://www.cnblogs.com/Monster-su/p/14512684.html
Copyright © 2011-2022 走看看