美文网首页
Arrays.sort()

Arrays.sort()

作者: 偕_2bb8 | 来源:发表于2020-10-11 12:54 被阅读0次

    对于基本类型数组 int[],long[],short[],long[],byte[],char[],float[],double[]使用双轴快排即Dual-Pivot Quicksort。

    jdk1.7之后采用的Dual-Pivot Quicksort,属于快排的变形。
    一般的快速排序采用一个枢轴来把一个数组划分成两半,然后递归之。
    大量经验数据表面,采用两个枢轴来划分成3份的算法更高效,这就是DualPivotQuicksort。
    下面以int[]类型为例 展示源码

        public static void sort(int[] a) {
            DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
        }
    
        static void sort(int[] a, int left, int right,
                         int[] work, int workBase, int workLen) {
            // Use Quicksort on small arrays
            if (right - left < QUICKSORT_THRESHOLD) {
                sort(a, left, right, true);
                return;
            }
    
            /*
             * Index run[i] is the start of i-th run
             * (ascending or descending sequence).
             */
            int[] run = new int[MAX_RUN_COUNT + 1];
            int count = 0; run[0] = left;
    
            // Check if the array is nearly sorted
            for (int k = left; k < right; run[count] = k) {
                if (a[k] < a[k + 1]) { // ascending
                    while (++k <= right && a[k - 1] <= a[k]);
                } else if (a[k] > a[k + 1]) { // descending
                    while (++k <= right && a[k - 1] >= a[k]);
                    for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
                        int t = a[lo]; a[lo] = a[hi]; a[hi] = t;
                    }
                } else { // equal
                    for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
                        if (--m == 0) {
                            sort(a, left, right, true);
                            return;
                        }
                    }
                }
    
                /*
                 * The array is not highly structured,
                 * use Quicksort instead of merge sort.
                 */
                if (++count == MAX_RUN_COUNT) {
                    sort(a, left, right, true);
                    return;
                }
            }
    
            // Check special cases
            // Implementation note: variable "right" is increased by 1.
            if (run[count] == right++) { // The last run contains one element
                run[++count] = right;
            } else if (count == 1) { // The array is already sorted
                return;
            }
    
            // Determine alternation base for merge
            byte odd = 0;
            for (int n = 1; (n <<= 1) < count; odd ^= 1);
    
            // Use or create temporary array b for merging
            int[] b;                 // temp array; alternates with a
            int ao, bo;              // array offsets from 'left'
            int blen = right - left; // space needed for b
            if (work == null || workLen < blen || workBase + blen > work.length) {
                work = new int[blen];
                workBase = 0;
            }
            if (odd == 0) {
                System.arraycopy(a, left, work, workBase, blen);
                b = a;
                bo = 0;
                a = work;
                ao = workBase - left;
            } else {
                b = work;
                ao = 0;
                bo = workBase - left;
            }
    
            // Merging
            for (int last; count > 1; count = last) {
                for (int k = (last = 0) + 2; k <= count; k += 2) {
                    int hi = run[k], mi = run[k - 1];
                    for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {
                        if (q >= hi || p < mi && a[p + ao] <= a[q + ao]) {
                            b[i + bo] = a[p++ + ao];
                        } else {
                            b[i + bo] = a[q++ + ao];
                        }
                    }
                    run[++last] = hi;
                }
                if ((count & 1) != 0) {
                    for (int i = right, lo = run[count - 1]; --i >= lo;
                        b[i + bo] = a[i + ao]
                    );
                    run[++last] = right;
                }
                int[] t = a; a = b; b = t;
                int o = ao; ao = bo; bo = o;
            }
        }
    
    对于对象数组Object[] 采用归并排序

    jdk1.8

        public static void sort(Object[] a) {
            if (LegacyMergeSort.userRequested)
                legacyMergeSort(a);
            else
                ComparableTimSort.sort(a, 0, a.length, null, 0, 0);
        }
    
        /** To be removed in a future release. */
        private static void legacyMergeSort(Object[] a) {
            Object[] aux = a.clone();
            mergeSort(aux, a, 0, a.length, 0);
        }
        /**
         * Src is the source array that starts at index 0
         * Dest is the (possibly larger) array destination with a possible offset
         * low is the index in dest to start sorting
         * high is the end index in dest to end sorting
         * off is the offset to generate corresponding low, high in src
         * To be removed in a future release.
         */
        @SuppressWarnings({"unchecked", "rawtypes"})
        private static void mergeSort(Object[] src, Object[] dest, int low, int high, int off) {
            int length = high - low;
    
            // Insertion sort on smallest arrays
            if (length < INSERTIONSORT_THRESHOLD) {
                for (int i=low; i<high; i++)
                    for (int j=i; j>low &&
                             ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
                        swap(dest, j, j-1);
                return;
            }
    
            // Recursively sort halves of dest into src
            int destLow  = low;
            int destHigh = high;
            low  += off;
            high += off;
            int mid = (low + high) >>> 1;
            mergeSort(dest, src, low, mid, -off);
            mergeSort(dest, src, mid, high, -off);
    
            // If list is already sorted, just copy from src to dest.  This is an
            // optimization that results in faster sorts for nearly ordered lists.
            if (((Comparable)src[mid-1]).compareTo(src[mid]) <= 0) {
                System.arraycopy(src, low, dest, destLow, length);
                return;
            }
    
            // Merge sorted halves (now in src) into dest
            for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
                if (q >= high || p < mid && ((Comparable)src[p]).compareTo(src[q])<=0)
                    dest[i] = src[p++];
                else
                    dest[i] = src[q++];
            }
        }
    
    Integer数组按绝对值大小排序
           Integer[] B = new Integer[10];
           //B赋值
           /*第1种*/
           Arrays.sort(B, Comparator.comparingInt(Math::abs));
           /*第2种*/
           Arrays.sort(B, new Comparator<Integer>() {
               @Override
               public int compare(Integer o1, Integer o2) {
                   return Math.abs(o1)-Math.abs(o2);
               }
           });
           /*第3种*/
           Arrays.sort(B,((o1, o2) -> Math.abs(o1)>Math.abs(o2)?1:-1));
    

    其他排序:

    1. 数字排序
    Arrays.sort(intArray);
    

    输出: [-23, 1, 3, 4]

    1. 字符串排序,先大写后小写
    Arrays.sort(strArray);
    

    输出: [C, a, z]

    1. 严格按字母表顺序(实际上是按照ASCII码)排序,也就是忽略大小写排序 Case-insensitive sort
    Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
    //关于String.CASE_INSENSITIVE_ORDER的作用https://blog.csdn.net/bbs_baibisen/article/details/80764446
    

    输出: [a, C, z]

    1. 反向排序, Reverse-order sort
    Arrays.sort(strArray, Collections.reverseOrder());
    

    输出:[z, a, C]

    1. 忽略大小写反向排序 Case-insensitive reverse-order sort
    Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
    Collections.reverse(Arrays.asList(strArray));
    

    输出: [z, C, a]

    Collections.sort()
        public static <T extends Comparable<? super T>> void sort(List<T> list) {
            list.sort(null);
        }
    
        default void sort(Comparator<? super E> c) {
            Object[] a = this.toArray();//集合转化为Object[]
            Arrays.sort(a, (Comparator) c);//底层还是调用Arrays.sort()
            ListIterator<E> i = this.listIterator();
            for (Object e : a) {
                i.next();
                i.set((E) e);
            }
        }
    

    相关文章

      网友评论

          本文标题:Arrays.sort()

          本文链接:https://www.haomeiwen.com/subject/qsltpktx.html