Arrays.sort()源码分析

static void sort(Object[] a, int lo, int hi, Object[] work, int workBase, int workLen) {
assert a != null && lo >= 0 && lo <= hi && hi <= a.length;

                 int nRemaining  = hi - lo;
                 if (nRemaining < 2)
                     return;  // array的大小为0或者1就不用排了

                 // 当数组大小小于MIN_MERGE(32)的时候,就用一个"mini-TimSort"的方法排序,jdk1.7新加
                 if (nRemaining < MIN_MERGE) {
                    //这个方法比较有意思,其实就是将我们最长的递减序列,找出来,然后倒过来
                     int initRunLen = countRunAndMakeAscending(a, lo, hi);
                     //长度小于32的时候,是使用binarySort插入排序
                     binarySort(a, lo, hi, lo + initRunLen);
                     return;
                 }
                //先扫描一次array,找到已经排好的序列,然后再用刚才的mini-TimSort,然后合并,这就是TimSort的核心思想
                 ComparableTimSort ts = new ComparableTimSort(a, work, workBase, workLen);
                 int minRun = minRunLength(nRemaining);
                 do {
                     // Identify next run
                     int runLen = countRunAndMakeAscending(a, lo, hi);

                     // 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);
                         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;
         }
private static <T> int countRunAndMakeAscending(T[] a, int lo, int hi,
                                                Comparator<? super T> c) {
    assert lo < hi;
    int runHi = lo + 1;
    if (runHi == hi)
        return 1;

    // Find end of run, and reverse range if descending
    if (c.compare(a[runHi++], a[lo]) < 0) { // Descending
        while (runHi < hi && c.compare(a[runHi], a[runHi - 1]) < 0)
            runHi++;
        reverseRange(a, lo, runHi);
    } else {                              // Ascending
        while (runHi < hi && c.compare(a[runHi], a[runHi - 1]) >= 0)
            runHi++;
    }

    return runHi - lo;
}

 

posted on 2018-12-31 17:49  溪水静幽  阅读(386)  评论(0)    收藏  举报