Collections.sort() 排序算法 源码简介

版本1.70 点击进来的代码是这样的:   

《Collections.sort() 排序算法 源码简介》

    public static <T> void sort(List<T> list, Comparator<? super T> c) {
        Object[] a = list.toArray();
        Arrays.sort(a, (Comparator)c);
        ListIterator i = list.listIterator();
        for (int j=0; j<a.length; j++) {
            i.next();
            i.set(a[j]);
        }
    }

简单说下注释,稳定的、自适应的n lg(n)的。

源码里 实际调用的是数组的排序!!!   

    public static <T> void sort(T[] a, Comparator<? super T> c) {
        if (LegacyMergeSort.userRequested)
            legacyMergeSort(a, c);
        else
            TimSort.sort(a, c);
    }

《Collections.sort() 排序算法 源码简介》

在说下这里的注释,LegacyMergeSort.userRequested 会在之后的版本废弃掉,至少先不用管了,我们专心看TimSort。

点击去

《Collections.sort() 排序算法 源码简介》

    static <T> void sort(T[] a, Comparator<? super T> c) {
        sort(a, 0, a.length, c);
    }

再进去,呵呵哒,和python有一腿···

《Collections.sort() 排序算法 源码简介》

    static <T> void sort(T[] a, int lo, int hi, Comparator<? super T> c) {
        if (c == null) {
            Arrays.sort(a, lo, hi);
            return;
        }

        rangeCheck(a.length, lo, hi);
        int nRemaining  = hi - lo;
        if (nRemaining < 2)
            return;  // Arrays of size 0 and 1 are always sorted

        // If array is small, do a "mini-TimSort" with no merges
        if (nRemaining < MIN_MERGE) {
            int initRunLen = countRunAndMakeAscending(a, lo, hi, c);
            binarySort(a, lo, hi, lo + initRunLen, c);
            return;
        }

        /**
         * March over the array once, left to right, finding natural runs,
         * extending short natural runs to minRun elements, and merging runs
         * to maintain stack invariant.
         */
        TimSort<T> ts = new TimSort<>(a, c);
        int minRun = minRunLength(nRemaining);
        do {
            // Identify next run
            int runLen = countRunAndMakeAscending(a, lo, hi, c);

            // If run is short, extend to min(minRun, nRemaining)
            if (runLen < minRun) {
                int force = nRemaining <= minRun ? nRemaining : minRun;
                binarySort(a, lo, lo + force, lo + runLen, c);
                runLen = force;
            }

            // Push run onto pending-run stack, and maybe merge
            ts.pushRun(lo, runLen);
            ts.mergeCollapse();

            // Advance to find next run
            lo += runLen;
            nRemaining -= runLen;
        } while (nRemaining != 0);

        // Merge all remaining runs to complete sort
        assert lo == hi;
        ts.mergeForceCollapse();
        assert ts.stackSize == 1;
    }

继续看,大致的意思是TimSort 本来 属于mergeSort的一种改进,引入binarySort进行子数组的排序,实现优化(原来的子数组排序是采用的选择排序),每次进行子数组合并的时候会进行一些特殊的处理来进行对一些特殊情况的优化。

总言之,这是个稳定、 时间复杂度是O(nlogn)   , 空间复杂度是O(n) 


点赞