TimSort Java源碼我的解讀

 1 /*JDK 1.8  2  */
 3 
 4 package java.util;  5 
 6 /**
 7  * A stable, adaptive, iterative mergesort that requires far fewer than  8  * n lg(n) comparisons when running on partially sorted arrays, while  9  * offering performance comparable to a traditional mergesort when run  10  * on random arrays. Like all proper mergesorts, this sort is stable and  11  * runs O(n log n) time (worst case). In the worst case, this sort requires  12  * temporary storage space for n/2 object references; in the best case,  13  * it requires only a small constant amount of space.  14  *  15  * This implementation was adapted from Tim Peters's list sort for  16  * Python, which is described in detail here:  17  *  18  * http://svn.python.org/projects/python/trunk/Objects/listsort.txt
 19  *  20  * Tim's C code may be found here:  21  *  22  * http://svn.python.org/projects/python/trunk/Objects/listobject.c
 23  *  24  * The underlying techniques are described in this paper (and may have  25  * even earlier origins):  26  *  27  * "Optimistic Sorting and Information Theoretic Complexity"  28  * Peter McIlroy  29  * SODA (Fourth Annual ACM-SIAM Symposium on Discrete Algorithms),  30  * pp 467-474, Austin, Texas, 25-27 January 1993.  31  *  32  * While the API to this class consists solely of static methods, it is  33  * (privately) instantiable; a TimSort instance holds the state of an ongoing  34  * sort, assuming the input array is large enough to warrant the full-blown  35  * TimSort. Small arrays are sorted in place, using a binary insertion sort.  36  *  37  * @author Josh Bloch  38  */
 39 class TimSort<T> {  40     /**
 41  * This is the minimum sized sequence that will be merged. Shorter  42  * sequences will be lengthened by calling binarySort. If the entire  43  * array is less than this length, no merges will be performed.  44  *  45  * This constant should be a power of two. It was 64 in Tim Peter's C  46  * implementation, but 32 was empirically determined to work better in  47  * this implementation. In the unlikely event that you set this constant  48  * to be a number that's not a power of two, you'll need to change the  49  * {@link #minRunLength} computation.  50  *  51  * If you decrease this constant, you must change the stackLen  52  * computation in the TimSort constructor, or you risk an  53  * ArrayOutOfBounds exception. See listsort.txt for a discussion  54  * of the minimum stack length required as a function of the length  55  * of the array being sorted and the minimum merge sequence length.  56      */
 57     private static final int MIN_MERGE = 32;  58 
 59     /**
 60  * The array being sorted.  61      */
 62     private final T[] a;  63 
 64     /**
 65  * The comparator for this sort.  66      */
 67     private final Comparator<? super T> c;  68 
 69     /**
 70  * When we get into galloping mode, we stay there until both runs win less  71  * often than MIN_GALLOP consecutive times.  72      */
 73     private static final int  MIN_GALLOP = 7;  74 
 75     /**
 76  * This controls when we get *into* galloping mode. It is initialized  77  * to MIN_GALLOP. The mergeLo and mergeHi methods nudge it higher for  78  * random data, and lower for highly structured data.  79      */
 80     private int minGallop = MIN_GALLOP;  81 
 82     /**
 83  * Maximum initial size of tmp array, which is used for merging. The array  84  * can grow to accommodate demand.  85  *  86  * Unlike Tim's original C version, we do not allocate this much storage  87  * when sorting smaller arrays. This change was required for performance.  88      */
 89     private static final int INITIAL_TMP_STORAGE_LENGTH = 256;  90 
 91     /**
 92  * Temp storage for merges. A workspace array may optionally be  93  * provided in constructor, and if so will be used as long as it  94  * is big enough.  95      */
 96     private T[] tmp;  97     private int tmpBase; // base of tmp array slice
 98     private int tmpLen;  // length of tmp array slice
 99 
 100     /**
 101  * A stack of pending runs yet to be merged. Run i starts at  102  * address base[i] and extends for len[i] elements. It's always  103  * true (so long as the indices are in bounds) that:  104  *  105  * runBase[i] + runLen[i] == runBase[i + 1]  106  *  107  * so we could cut the storage for this, but it's a minor amount,  108  * and keeping all the info explicit simplifies the code.  109      */
 110     private int stackSize = 0;  // Number of pending runs on stack
 111     private final int[] runBase;  112     private final int[] runLen;  113 
 114     /**
 115  * Creates a TimSort instance to maintain the state of an ongoing sort.  116  *  117  * @param a the array to be sorted  118  * @param c the comparator to determine the order of the sort  119  * @param work a workspace array (slice)  120  * @param workBase origin of usable space in work array  121  * @param workLen usable size of work array  122      */
 123     private TimSort(T[] a, Comparator<? super T> c, T[] work, int workBase, int workLen) {  124         this.a = a;  125         this.c = c;  126 
 127         // Allocate temp storage (which may be increased later if necessary)
 128         int len = a.length;  129         // 肯定臨時數組的長度, 若是低於默認值256的2倍, 則空間大小爲原始數組a的長度乘以2, 不然爲默認長度
 130         int tlen = (len < 2 * INITIAL_TMP_STORAGE_LENGTH) ?
 131             len >>> 1 : INITIAL_TMP_STORAGE_LENGTH;  132         if (work == null || workLen < tlen || workBase + tlen > work.length) {  133             @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"})  134             T[] newArray = (T[])java.lang.reflect.Array.newInstance  135  (a.getClass().getComponentType(), tlen);  136             tmp = newArray;  137             tmpBase = 0;  138             tmpLen = tlen;  139  }  140         else {  141             // 當指定的work數組不爲空, 且workLen大於計算出的tlen的長度, 而且work數組的有效長度大於tlen的長度時, 使用指定的臨時數組
 142             tmp = work;  143             tmpBase = workBase;  144             tmpLen = workLen;  145  }  146 
 147         /*
 148  * Allocate runs-to-be-merged stack (which cannot be expanded). The  149  * stack length requirements are described in listsort.txt. The C  150  * version always uses the same stack length (85), but this was  151  * measured to be too expensive when sorting "mid-sized" arrays (e.g.,  152  * 100 elements) in Java. Therefore, we use smaller (but sufficiently  153  * large) stack lengths for smaller arrays. The "magic numbers" in the  154  * computation below must be changed if MIN_MERGE is decreased. See  155  * the MIN_MERGE declaration above for more information.  156  * The maximum value of 49 allows for an array up to length  157  * Integer.MAX_VALUE-4, if array is filled by the worst case stack size  158  * increasing scenario. More explanations are given in section 4 of:  159  * http://envisage-project.eu/wp-content/uploads/2015/02/sorting.pdf
 160          */
 161         int stackLen = (len <    120  ?  5 :  162                         len <   1542  ? 10 :  163                         len < 119151  ? 24 : 49);  164         runBase = new int[stackLen];  165         runLen = new int[stackLen];  166  }  167 
 168     /*
 169  * The next method (package private and static) constitutes the  170  * entire API of this class.  171      */
 172 
 173     /**
 174  * Sorts the given range, using the given workspace array slice  175  * for temp storage when possible. This method is designed to be  176  * invoked from public methods (in class Arrays) after performing  177  * any necessary array bounds checks and expanding parameters into  178  * the required forms.  179  *  180  * @param a the array to be sorted  181  * @param lo the index of the first element, inclusive, to be sorted  182  * @param hi the index of the last element, exclusive, to be sorted  183  * @param c the comparator to use  184  * @param work a workspace array (slice)  185  * @param workBase origin of usable space in work array  186  * @param workLen usable size of work array  187  * @since 1.8  188      */
 189     static <T> void sort(T[] a, int lo, int hi, Comparator<? super T> c,  190                          T[] work, int workBase, int workLen) {  191         assert c != null && a != null && lo >= 0 && lo <= hi && hi <= a.length;  192 
 193         int nRemaining  = hi - lo;        //總共的待排序的元素個數
 194         if (nRemaining < 2)  195             return;  // Arrays of size 0 and 1 are always sorted  196 
 197         // If array is small, do a "mini-TimSort" with no merges  198         // 當元素個數小於7時, 使用折半插入排序, 由於插入排序對於元素個數少的數組更快。
 199         if (nRemaining < MIN_MERGE) {  200             // initRunLen是初始的有序的元素的個數,而從索引位置lo + initRunLen開始, 後面爲亂序的元素。 一種優化方法, lo + initRunLen以前的不用排序了
 201             int initRunLen = countRunAndMakeAscending(a, lo, hi, c);  202             // 折半插入排序
 203             binarySort(a, lo, hi, lo + initRunLen, c);  204             return;  205  }  206 
 207         /**
 208  * March over the array once, left to right, finding natural runs,  209  * extending short natural runs to minRun elements, and merging runs  210  * to maintain stack invariant.  211          */
 212          // 新建一個TimSort實例, 存儲運行時的狀態, 好比臨時的run(一個run即一個有序的數組)
 213         TimSort<T> ts = new TimSort<>(a, c, work, workBase, workLen);  214         // 查找一個minRun值, 小於minRun時使用折半插入排序,MIN_MERGE/2 <= minRun <= MIN_MERGE
 215         int minRun = minRunLength(nRemaining);  216         do {  217             // Identify next run  218             // 找到下一個有序的數組的長度
 219             int runLen = countRunAndMakeAscending(a, lo, hi, c);  220 
 221             // If run is short, extend to min(minRun, nRemaining)
 222             if (runLen < minRun) {  223                 // 使用折半插入排序擴展數組, 使之達到minRun, 由於元素個數小於minRun, 折半插入排序更快速
 224                 int force = nRemaining <= minRun ? nRemaining : minRun;  225                 binarySort(a, lo, lo + force, lo + runLen, c);  226                 runLen = force;  227  }  228 
 229             // Push run onto pending-run stack, and maybe merge  230             // 把這個有序數組壓入棧中
 231  ts.pushRun(lo, runLen);  232             /**
 233  * 判斷當  234  * runLen[i - 3] <= runLen[i - 2] + runLen[i - 1]  235  * 且 runLen[i-3] < runLen[i-1]時  236  * 或  237  * runLen[i - 2] <= runLen[i - 1]  238  * 合併較小的兩個有序數組, 以達到最大的平衡(即每一個數組大小基本相同)  239             */
 240  ts.mergeCollapse();  241 
 242             // Advance to find next run
 243             lo += runLen;  244             nRemaining -= runLen;  245         } while (nRemaining != 0);  246 
 247         // Merge all remaining runs to complete sort
 248         assert lo == hi;  249         //合併剩餘數組
 250  ts.mergeForceCollapse();  251         assert ts.stackSize == 1;  252  }  253 
 254     /**
 255  * Sorts the specified portion of the specified array using a binary  256  * insertion sort. This is the best method for sorting small numbers  257  * of elements. It requires O(n log n) compares, but O(n^2) data  258  * movement (worst case).  259  *  260  * If the initial part of the specified range is already sorted,  261  * this method can take advantage of it: the method assumes that the  262  * elements from index {@code lo}, inclusive, to {@code start},  263  * exclusive are already sorted.  264  *  265  * @param a the array in which a range is to be sorted  266  * @param lo the index of the first element in the range to be sorted  267  * @param hi the index after the last element in the range to be sorted  268  * @param start the index of the first element in the range that is  269  * not already known to be sorted ({@code lo <= start <= hi})  270  * @param c comparator to used for the sort  271      */
 272     @SuppressWarnings("fallthrough")  273     private static <T> void binarySort(T[] a, int lo, int hi, int start,  274                                        Comparator<? super T> c) {  275         assert lo <= start && start <= hi;  276         // start以前的有序元素直接略過
 277         if (start == lo)  278             start++;  279         // 從start到hi, 使用折半插入排序進行數組排序
 280         for ( ; start < hi; start++) {  281             //待插入的元素
 282             T pivot = a[start];  283 
 284             // Set left (and right) to the index where a[start] (pivot) belongs  285             // 從left到right, 找到插入位置
 286             int left = lo;  287             int right = start;  288             assert left <= right;  289             /*
 290  * Invariants:  291  * pivot >= all in [lo, left).  292  * pivot < all in [right, start).  293              */
 294             while (left < right) {  295                 int mid = (left + right) >>> 1;  296                 if (c.compare(pivot, a[mid]) < 0)  297                     right = mid;  298                 else
 299                     left = mid + 1;  300  }  301             // left即爲最終的插入位置, 由於start>=lo && start <=hi, 因此最終必定會找到一個位置使得pivot>=a[mid], 所以最終必定是pivot >= right, 所以最終爲left的位置, 即mid+1
 302             assert left == right;  303 
 304             /*
 305  * The invariants still hold: pivot >= all in [lo, left) and  306  * pivot < all in [left, start), so pivot belongs at left. Note  307  * that if there are elements equal to pivot, left points to the  308  * first slot after them -- that's why this sort is stable.  309  * Slide elements over to make room for pivot.  310              */
 311             int n = start - left;  // The number of elements to move  312             // Switch is just an optimization for arraycopy in default case
 313             switch (n) {  314                 case 2:  a[left + 2] = a[left + 1]; // 若是待移動元素個數小於等於2則直接移動
 315                 case 1:  a[left + 1] = a[left];  316                          break;  317                 default: System.arraycopy(a, left, a, left + 1, n);  // 從left開始日後移, 而後把start位置的元素插入到原來的left的位置
 318  }  319             a[left] = pivot;  320  }  321  }  322 
 323     /**
 324  * Returns the length of the run beginning at the specified position in  325  * the specified array and reverses the run if it is descending (ensuring  326  * that the run will always be ascending when the method returns).  327  *  328  * A run is the longest ascending sequence with:  329  *  330  * a[lo] <= a[lo + 1] <= a[lo + 2] <= ...  331  *  332  * or the longest descending sequence with:  333  *  334  * a[lo] > a[lo + 1] > a[lo + 2] > ...  335  *  336  * For its intended use in a stable mergesort, the strictness of the  337  * definition of "descending" is needed so that the call can safely  338  * reverse a descending sequence without violating stability.  339  *  340  * @param a the array in which a run is to be counted and possibly reversed  341  * @param lo index of the first element in the run  342  * @param hi index after the last element that may be contained in the run.  343  It is required that {@code lo < hi}.  344  * @param c the comparator to used for the sort  345  * @return the length of the run beginning at the specified position in  346  * the specified array  347      */
 348     private static <T> int countRunAndMakeAscending(T[] a, int lo, int hi,  349                                                     Comparator<? super T> c) {  350         assert lo < hi;  351         int runHi = lo + 1;  352         if (runHi == hi)  353             return 1;  // lo < hi, 且lo + 1 = hi, 所以是有序且升序的, 直接返回  354 
 355         // Find end of run, and reverse range if descending
 356         if (c.compare(a[runHi++], a[lo]) < 0) { // Descending  357             // 若是是降序的, 找到最長的有序降序序列的長度, 而且把序列倒置, 使之升序
 358             while (runHi < hi && c.compare(a[runHi], a[runHi - 1]) < 0)  359                 runHi++;  360  reverseRange(a, lo, runHi);  361         } else {                              // Ascending  362             // 若是是升序的, 一樣找到最長的有序序列的長度
 363             while (runHi < hi && c.compare(a[runHi], a[runHi - 1]) >= 0)  364                 runHi++;  365  }  366 
 367         // 返回有序序列的長度
 368         return runHi - lo;  369  }  370 
 371     /**
 372  * Reverse the specified range of the specified array.  373  *  374  * @param a the array in which a range is to be reversed  375  * @param lo the index of the first element in the range to be reversed  376  * @param hi the index after the last element in the range to be reversed  377      */
 378     private static void reverseRange(Object[] a, int lo, int hi) {  379         hi--;  380         // 首尾倒置
 381         while (lo < hi) {  382             Object t = a[lo];  383             a[lo++] = a[hi];  384             a[hi--] = t;  385  }  386  }  387 
 388     /**
 389  * Returns the minimum acceptable run length for an array of the specified  390  * length. Natural runs shorter than this will be extended with  391  * {@link #binarySort}.  392  *  393  * Roughly speaking, the computation is:  394  *  395  * If n < MIN_MERGE, return n (it's too small to bother with fancy stuff).  396  * Else if n is an exact power of 2, return MIN_MERGE/2.  397  * Else return an int k, MIN_MERGE/2 <= k <= MIN_MERGE, such that n/k  398  * is close to, but strictly less than, an exact power of 2.  399  *  400  * For the rationale, see listsort.txt.  401  *  402  * @param n the length of the array to be sorted  403  * @return the length of the minimum run to be merged  404      */
 405     private static int minRunLength(int n) {  406         assert n >= 0;  407         int r = 0;      // Becomes 1 if any 1 bits are shifted off
 408         while (n >= MIN_MERGE) {  409             // n&1是判斷n是可否被2整除, 若是不能被2整除, 最後一個Bit位必定是1,則1&1爲1, r = r | 1 爲1
 410             r |= (n & 1);  411             n >>= 1;  412  }  413         return n + r;  414  }  415 
 416     /**
 417  * Pushes the specified run onto the pending-run stack.  418  *  419  * @param runBase index of the first element in the run  420  * @param runLen the number of elements in the run  421      */
 422      // 把有序序列起始位置和長度放入棧中
 423     private void pushRun(int runBase, int runLen) {  424         this.runBase[stackSize] = runBase;  425         this.runLen[stackSize] = runLen;  426         stackSize++;  427  }  428 
 429     /**
 430  * Examines the stack of runs waiting to be merged and merges adjacent runs  431  * until the stack invariants are reestablished:  432  *  433  * 1. runLen[i - 3] > runLen[i - 2] + runLen[i - 1]  434  * 2. runLen[i - 2] > runLen[i - 1]  435  *  436  * This method is called each time a new run is pushed onto the stack,  437  * so the invariants are guaranteed to hold for i < stackSize upon  438  * entry to the method.  439      */
 440      // 判斷合併棧頂的三個元素中較小的兩個, 或若是第二個元素比第一個小, 則合併, 使棧中全部的序列大小達到近似相等
 441     private void mergeCollapse() {  442         while (stackSize > 1) {  443             int n = stackSize - 2;  444             if (n > 0 && runLen[n-1] <= runLen[n] + runLen[n+1]) {  445                 if (runLen[n - 1] < runLen[n + 1])  446                     n--;  447  mergeAt(n);  448             } else if (runLen[n] <= runLen[n + 1]) {  449  mergeAt(n);  450             } else {  451                 break; // Invariant is established
 452  }  453  }  454  }  455 
 456     /**
 457  * Merges all runs on the stack until only one remains. This method is  458  * called once, to complete the sort.  459      */
 460      // 最後合併棧中全部的序列, 直到最後只剩一個有序序列
 461     private void mergeForceCollapse() {  462         while (stackSize > 1) {  463             int n = stackSize - 2;  464             // 若是runLen[n-1] < runLen[n+1], 則合併較小的較小的runBase[n-1]和runBase[n], 不然合併runBase[n]和runBase[n+1]
 465             if (n > 0 && runLen[n - 1] < runLen[n + 1])  466                 n--;  467  mergeAt(n);  468  }  469  }  470 
 471     /**
 472  * Merges the two runs at stack indices i and i+1. Run i must be  473  * the penultimate or antepenultimate run on the stack. In other words,  474  * i must be equal to stackSize-2 or stackSize-3.  475  *  476  * @param i stack index of the first of the two runs to merge  477      */
 478     private void mergeAt(int i) {  479         assert stackSize >= 2;  480         assert i >= 0;  481         assert i == stackSize - 2 || i == stackSize - 3;  482 
 483         int base1 = runBase[i];  484         int len1 = runLen[i];  485         int base2 = runBase[i + 1];  486         int len2 = runLen[i + 1];  487         assert len1 > 0 && len2 > 0;  488         assert base1 + len1 == base2;  489 
 490         /*
 491  * Record the length of the combined runs; if i is the 3rd-last  492  * run now, also slide over the last run (which isn't involved  493  * in this merge). The current run (i+1) goes away in any case.  494          */
 495         runLen[i] = len1 + len2;  496         // 若是i是棧頂倒數第三個元素, 則最後i+1必定會合進i數組, 所以i+1的位置替換成i+2
 497         if (i == stackSize - 3) {  498             runBase[i + 1] = runBase[i + 2];  499             runLen[i + 1] = runLen[i + 2];  500  }  501         stackSize--;  502 
 503         /*
 504  * Find where the first element of run2 goes in run1. Prior elements  505  * in run1 can be ignored (because they're already in place).  506          */
 507          // 找到run2的首元素在run1中的位置
 508         int k = gallopRight(a[base2], a, base1, len1, 0, c);  509         assert k >= 0;  510         // 忽略k以前的序列, 由於已經有序, 減小比較次數
 511         base1 += k;  512         len1 -= k;  513         if (len1 == 0)  514             return;  515 
 516         /*
 517  * Find where the last element of run1 goes in run2. Subsequent elements  518  * in run2 can be ignored (because they're already in place).  519          */
 520          // 找打run1的尾元素在run2中的位置
 521         len2 = gallopLeft(a[base1 + len1 - 1], a, base2, len2, len2 - 1, c);  522         assert len2 >= 0;  523         // len2 == 0, 說明run1和run2已是一個總體有序的序列了, 直接返回。
 524         if (len2 == 0)  525             return;  526 
 527         // Merge remaining runs, using tmp array with min(len1, len2) elements
 528         if (len1 <= len2)  529  mergeLo(base1, len1, base2, len2);  530         else
 531  mergeHi(base1, len1, base2, len2);  532  }  533 
 534     /**
 535  * Locates the position at which to insert the specified key into the  536  * specified sorted range; if the range contains an element equal to key,  537  * returns the index of the leftmost equal element.  538  *  539  * @param key the key whose insertion point to search for  540  * @param a the array in which to search  541  * @param base the index of the first element in the range  542  * @param len the length of the range; must be > 0  543  * @param hint the index at which to begin the search, 0 <= hint < n.  544  * The closer hint is to the result, the faster this method will run.  545  * @param c the comparator used to order the range, and to search  546  * @return the int k, 0 <= k <= n such that a[b + k - 1] < key <= a[b + k],  547  * pretending that a[b - 1] is minus infinity and a[b + n] is infinity.  548  * In other words, key belongs at index b + k; or in other words,  549  * the first k elements of a should precede key, and the last n - k  550  * should follow it.  551      */
 552     private static <T> int gallopLeft(T key, T[] a, int base, int len, int hint,  553                                       Comparator<? super T> c) {  554         assert len > 0 && hint >= 0 && hint < len;  555         int lastOfs = 0;  556         int ofs = 1;  557         if (c.compare(key, a[base + hint]) > 0) {  558             // 查找區間[base + hint, len], 查找使得a[base+hint+lastOfs] < key <= a[base+hint+ofs]成立的ofs值。
 559             int maxOfs = len - hint;  560             // 向右查找, 最大可能Ofs爲maxOfs-1, 即len - hint - 1, 即a[base + len - 1]
 561             while (ofs < maxOfs && c.compare(key, a[base + hint + ofs]) > 0) {  562                 // 記錄上一次ofs的值, 存到lastOfs中
 563                 lastOfs = ofs;  564                 // ofs乘以2再加1
 565                 ofs = (ofs << 1) + 1;  566                 // 整數溢出
 567                 if (ofs <= 0)  568                     ofs = maxOfs;  569  }  570             
 571             // ofs最大值爲maxOfs
 572             if (ofs > maxOfs)  573                 ofs = maxOfs;  574 
 575             // Make offsets relative to base  576             // 以前的ofs和lastOfs都是相對於hint位置的, 如今把它重置爲相對於base的位置
 577             lastOfs += hint;  578             ofs += hint;  579         } else { // key <= a[base + hint]  580             // 從base+hint向前搜索,查找區間[base, base + hint], 直到找到ofs值使得a[base+hint-ofs] < key <= a[base+hint-lastOfs]  581             // maxOfs爲hint+1, 而ofs < maxOfs, 所以當ofs = maxOfs -1 時, 比較到的最左邊的元素爲a[base + hint - hint] == a[base]
 582             final int maxOfs = hint + 1;  583             while (ofs < maxOfs && c.compare(key, a[base + hint - ofs]) <= 0) {  584                 lastOfs = ofs;  585                 // ofs乘以2再加1
 586                 ofs = (ofs << 1) + 1;  587                 // 正整數溢出
 588                 if (ofs <= 0)  589                     ofs = maxOfs;  590  }  591             // 最大爲maxOfs
 592             if (ofs > maxOfs)  593                 ofs = maxOfs;  594 
 595             // 重置ofs和lastOfs爲相對於base的位置索引
 596             int tmp = lastOfs;  597             lastOfs = hint - ofs;  598             ofs = hint - tmp;  599  }  600         assert -1 <= lastOfs && lastOfs < ofs && ofs <= len;  601 
 602         /*
 603  * Now a[base+lastOfs] < key <= a[base+ofs], so key belongs somewhere  604  * to the right of lastOfs but no farther right than ofs. Do a binary  605  * search, with invariant a[base + lastOfs - 1] < key <= a[base + ofs].  606          */
 607         lastOfs++;  608         // 查找準確位置
 609         while (lastOfs < ofs) {  610             // 中間位置
 611             int m = lastOfs + ((ofs - lastOfs) >>> 1);  612 
 613             if (c.compare(key, a[base + m]) > 0)  614                 lastOfs = m + 1;  // a[base + m] < key
 615             else
 616                 ofs = m;          // key <= a[base + m]
 617  }  618         assert lastOfs == ofs;    // so a[base + ofs - 1] < key <= a[base + ofs]
 619         return ofs;  620  }  621 
 622     /**
 623  * Like gallopLeft, except that if the range contains an element equal to  624  * key, gallopRight returns the index after the rightmost equal element.  625  *  626  * @param key the key whose insertion point to search for  627  * @param a the array in which to search  628  * @param base the index of the first element in the range  629  * @param len the length of the range; must be > 0  630  * @param hint the index at which to begin the search, 0 <= hint < n.  631  * The closer hint is to the result, the faster this method will run.  632  * @param c the comparator used to order the range, and to search  633  * @return the int k, 0 <= k <= n such that a[b + k - 1] <= key < a[b + k]  634      */
 635     private static <T> int gallopRight(T key, T[] a, int base, int len,  636                                        int hint, Comparator<? super T> c) {  637         assert len > 0 && hint >= 0 && hint < len;  638 
 639         int ofs = 1;  640         int lastOfs = 0;  641         if (c.compare(key, a[base + hint]) < 0) {  642             // 從base + hint位置向前搜索區間[base, base + hint], 使得a[b+hint - ofs] <= key < a[b+hint - lastOfs]
 643             int maxOfs = hint + 1;  644             while (ofs < maxOfs && c.compare(key, a[base + hint - ofs]) < 0) {  645                 // 記錄上次查找位置
 646                 lastOfs = ofs;  647                 // 乘以2 加1
 648                 ofs = (ofs << 1) + 1;  649                 // 正整數溢出
 650                 if (ofs <= 0)  651                     ofs = maxOfs;  652  }  653             // 最大爲maxOfs
 654             if (ofs > maxOfs)  655                 ofs = maxOfs;  656 
 657             // 重置ofs和lastOfs爲相對於base的位置索引
 658             int tmp = lastOfs;  659             lastOfs = hint - ofs;  660             ofs = hint - tmp;  661         } else { // a[b + hint] <= key  662             // 搜索區間[base + hint, base + len -1]使得a[b+hint + lastOfs] <= key < a[b+hint + ofs]
 663             int maxOfs = len - hint;  664             while (ofs < maxOfs && c.compare(key, a[base + hint + ofs]) >= 0) {  665                 lastOfs = ofs;  666                 ofs = (ofs << 1) + 1;  667                 // 正整數溢出
 668                 if (ofs <= 0)  669                     ofs = maxOfs;  670  }  671             if (ofs > maxOfs)  672                 ofs = maxOfs;  673 
 674             // 重置ofs和lastOfs爲相對於base的位置索引
 675             lastOfs += hint;  676             ofs += hint;  677  }  678         assert -1 <= lastOfs && lastOfs < ofs && ofs <= len;  679 
 680         lastOfs++;  681         // 查找key的準確位置
 682         while (lastOfs < ofs) {  683             int m = lastOfs + ((ofs - lastOfs) >>> 1);  684 
 685             if (c.compare(key, a[base + m]) < 0)  686                 ofs = m;          // key < a[b + m]
 687             else
 688                 lastOfs = m + 1;  // a[b + m] <= key
 689  }  690         // 最終會找到m使得k >= a[base + m], 而此時lastOfs == ofs且lastOfs = m +1, 則ofs = m +1, 所以a[base + ofs] > k >= a[base + ofs -1], ofs即m+1, ofs - 1即爲m, 所以ofs位置的值大於key
 691         assert lastOfs == ofs;    // so a[b + ofs - 1] <= key < a[b + ofs]
 692         return ofs;  693  }  694 
 695     /**
 696  *基於以上gallopRight方法最後查找key的索引的解釋, 所以run1的第一個元素必定大於run2的第一個元素, *而run2中run1最後一個元素所在索引位置以後的值也被忽略掉, 所以run1的最後一個元素大於run2中的全部元素的值。*/
 697     
 698     
 699     /**
 700  * Merges two adjacent runs in place, in a stable fashion. The first  701  * element of the first run must be greater than the first element of the  702  * second run (a[base1] > a[base2]), and the last element of the first run  703  * (a[base1 + len1-1]) must be greater than all elements of the second run.  704  *  705  * For performance, this method should be called only when len1 <= len2;  706  * its twin, mergeHi should be called if len1 >= len2. (Either method  707  * may be called if len1 == len2.)  708  *  709  * @param base1 index of first element in first run to be merged  710  * @param len1 length of first run to be merged (must be > 0)  711  * @param base2 index of first element in second run to be merged  712  * (must be aBase + aLen)  713  * @param len2 length of second run to be merged (must be > 0)  714      */
 715     private void mergeLo(int base1, int len1, int base2, int len2) {  716         assert len1 > 0 && len2 > 0 && base1 + len1 == base2;  717 
 718         // Copy first run into temp array
 719         T[] a = this.a; // For performance
 720         T[] tmp = ensureCapacity(len1);  721         int cursor1 = tmpBase; // Indexes into tmp array
 722         int cursor2 = base2;   // Indexes int a  723         // 目標位置從base1的索引開始, 由於base1在base2以前, 下面會將base1的內容放入臨時數組, 這樣run1中的內容就能夠覆蓋了
 724         int dest = base1;      // Indexes int a  725         // 把第一個序列的內容放入臨時數組tmp中
 726  System.arraycopy(a, base1, tmp, cursor1, len1);  727 
 728         // Move first element of second run and deal with degenerate cases  729         // 由於run1的第一個元素大於run2的第一個元素, 所以將run2的第一個元素先放進
 730         a[dest++] = a[cursor2++];  731         // 若是run2只有一個元素, 則將run1中剩餘的元素放入正確位置後返回
 732         if (--len2 == 0) {  733  System.arraycopy(tmp, cursor1, a, dest, len1);  734             return;  735  }  736         // 若是run1只有一個元素, 由於run1的最後一個元素大於run2中的全部元素, 所以先將run2中的元素放入正確位置, 而後將run1的惟一的一個元素放入最後一個位置, 而後返回
 737         if (len1 == 1) {  738  System.arraycopy(a, cursor2, a, dest, len2);  739             a[dest + len2] = tmp[cursor1]; // Last elt of run 1 to end of merge
 740             return;  741  }  742 
 743         Comparator<? super T> c = this.c;  // Use local variable for performance
 744         int minGallop = this.minGallop;    // " " " " "
 745  outer:  746         while (true) {  747             int count1 = 0; // Number of times in a row that first run won
 748             int count2 = 0; // Number of times in a row that second run won
 749 
 750             /*
 751  * Do the straightforward thing until (if ever) one run starts  752  * winning consistently.  753              */
 754             do {  755                 assert len1 > 1 && len2 > 0;  756                 if (c.compare(a[cursor2], tmp[cursor1]) < 0) {  757                     a[dest++] = a[cursor2++];  758                     count2++;  759                     count1 = 0;  760                     if (--len2 == 0)  761                         break outer;  762                 } else {  763                     a[dest++] = tmp[cursor1++];  764                     count1++;  765                     count2 = 0;  766                     if (--len1 == 1)  767                         break outer;  768  }  769                 // 當每一個序列中的連續放入目標位置的元素個數小於minGallop時, 這樣分別拷貝就能夠了
 770             } while ((count1 | count2) < minGallop);  771 
 772             /*
 773  * One run is winning so consistently that galloping may be a  774  * huge win. So try that, and continue galloping until (if ever)  775  * neither run appears to be winning consistently anymore.  776              */
 777              // 由於兩個run序列的大小是近似相等的, 若是一個序列連續超過minGallop個數的元素被放入目標位置, 則另外一個有接近大小的連續序列等待被放入正確位置,切換成Gallopping模式
 778             do {  779                 assert len1 > 1 && len2 > 0;  780                 //查找run1第一個大於run2中第一個元素的元素的位置索引
 781                 count1 = gallopRight(a[cursor2], tmp, cursor1, len1, 0, c);  782                 if (count1 != 0) {  783                     // run1中count1以前的元素所有放入目標序列
 784  System.arraycopy(tmp, cursor1, a, dest, count1);  785                     // 移動索引位置
 786                     dest += count1;  787                     cursor1 += count1;  788                     len1 -= count1;  789                     if (len1 <= 1) // len1 == 1 || len1 == 0
 790                         break outer;  791  }  792                 // 移動run2的第一個元素到目標序列中
 793                 a[dest++] = a[cursor2++];  794                 // 若是run2中沒有其餘元素則跳出
 795                 if (--len2 == 0)  796                     break outer;  797 
 798                 // 查找run2中第一個小於等於run1當前元素的元素的位置索引
 799                 count2 = gallopLeft(tmp[cursor1], a, cursor2, len2, 0, c);  800                 if (count2 != 0) {  801                     // 拷貝count2以後的元素到目標序列
 802  System.arraycopy(a, cursor2, a, dest, count2);  803                     dest += count2;  804                     cursor2 += count2;  805                     len2 -= count2;  806                     // run2中沒有其餘元素則跳出
 807                     if (len2 == 0)  808                         break outer;  809  }  810                 
 811                 // 此時run2中的第一個元素大於等於run1中的第一個元素, 拷貝run1中的第一個元素到目標序列
 812                 a[dest++] = tmp[cursor1++];  813                 // 若是run1中只有一個元素則跳出
 814                 if (--len1 == 1)  815                     break outer;  816                 // 動態調整minGallop的值
 817                 minGallop--;  818             } while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP);  819             if (minGallop < 0)  820                 minGallop = 0;  821             // 調整minGallop的值, 使得在有序序列很少的狀況下不用Gallopping模式
 822             minGallop += 2;  // Penalize for leaving gallop mode
 823         }  // End of "outer" loop
 824         this.minGallop = minGallop < 1 ? 1 : minGallop;  // Write back to field  825 
 826         // run1中只有一個元素
 827         if (len1 == 1) {  828             assert len2 > 0;  829  System.arraycopy(a, cursor2, a, dest, len2);  830             a[dest + len2] = tmp[cursor1]; // Last elt of run 1 to end of merge
 831         } else if (len1 == 0) {  832             // 由於run1中的最後一個元素大於run2中的全部元素, 所以這種狀況不存在
 833             throw new IllegalArgumentException(  834                 "Comparison method violates its general contract!");  835         } else {  836             // run2中已經沒有元素
 837             assert len2 == 0;  838             assert len1 > 1;  839  System.arraycopy(tmp, cursor1, a, dest, len1);  840  }  841  }  842 
 843     /**
 844  * Like mergeLo, except that this method should be called only if  845  * len1 >= len2; mergeLo should be called if len1 <= len2. (Either method  846  * may be called if len1 == len2.)  847  *  848  * @param base1 index of first element in first run to be merged  849  * @param len1 length of first run to be merged (must be > 0)  850  * @param base2 index of first element in second run to be merged  851  * (must be aBase + aLen)  852  * @param len2 length of second run to be merged (must be > 0)  853      */
 854     private void mergeHi(int base1, int len1, int base2, int len2) {  855         assert len1 > 0 && len2 > 0 && base1 + len1 == base2;  856 
 857         // Copy second run into temp array
 858         T[] a = this.a; // For performance
 859         T[] tmp = ensureCapacity(len2);  860         int tmpBase = this.tmpBase;  861         // 將run2中的全部元素放入臨時數組tmp中
 862  System.arraycopy(a, base2, tmp, tmpBase, len2);  863 
 864         int cursor1 = base1 + len1 - 1;  // Indexes into a
 865         int cursor2 = tmpBase + len2 - 1; // Indexes into tmp array  866         // 從後往前插入元素
 867         int dest = base2 + len2 - 1;     // Indexes into a  868 
 869         // Move last element of first run and deal with degenerate cases  870         // run1的最後一個元素導入目標位置
 871         a[dest--] = a[cursor1--];  872         // 若是run1中只有一個元素, 將run2中的剩餘元素放入目標位置(從後往前)
 873         if (--len1 == 0) {  874             System.arraycopy(tmp, tmpBase, a, dest - (len2 - 1), len2);  875             return;  876  }  877         if (len2 == 1) {  878             // run2中只有一個元素, 由於run1的第一個元素大於run2的第一個元素, 所以, run2中惟一的一個元素小於run1中全部的元素, 所以將run1中的元素所有放入目標位置, 最後將惟一的run2中的一個元素放入第一個位置
 879             dest -= len1;  880             cursor1 -= len1;  881             System.arraycopy(a, cursor1 + 1, a, dest + 1, len1);  882             a[dest] = tmp[cursor2];  883             return;  884  }  885 
 886         Comparator<? super T> c = this.c;  // Use local variable for performance
 887         int minGallop = this.minGallop;    // " " " " "
 888  outer:  889         while (true) {  890             int count1 = 0; // Number of times in a row that first run won
 891             int count2 = 0; // Number of times in a row that second run won
 892 
 893             /*
 894  * Do the straightforward thing until (if ever) one run  895  * appears to win consistently.  896              */
 897             do {  898                 assert len1 > 0 && len2 > 1;  899                 if (c.compare(tmp[cursor2], a[cursor1]) < 0) {  900                        // 從後往前放入目標位置
 901                     a[dest--] = a[cursor1--];  902                     count1++;  903                     count2 = 0;  904                     // run1中沒有了元素
 905                     if (--len1 == 0)  906                         break outer;  907                 } else {  908                     a[dest--] = tmp[cursor2--];  909                     count2++;  910                     count1 = 0;  911                     // run2中只有一個剩餘元素
 912                     if (--len2 == 1)  913                         break outer;  914  }  915             } while ((count1 | count2) < minGallop);  916 
 917             /*
 918  * One run is winning so consistently that galloping may be a  919  * huge win. So try that, and continue galloping until (if ever)  920  * neither run appears to be winning consistently anymore.  921              */
 922             do {  923                 assert len1 > 0 && len2 > 1;  924                 // 找到大於run2當前位置的元素的run1中元素, 由於是從後往前查找, 所以找到的位置好比k1,k1以後的全部元素大於run1, run2中的剩餘全部元素
 925                 count1 = len1 - gallopRight(tmp[cursor2], a, base1, len1, len1 - 1, c);  926                 if (count1 != 0) {  927                     dest -= count1;  928                     cursor1 -= count1;  929                     len1 -= count1;  930                     // 拷貝run1中的大的元素
 931                     System.arraycopy(a, cursor1 + 1, a, dest + 1, count1);  932                     // run1中沒有元素, 跳出
 933                     if (len1 == 0)  934                         break outer;  935  }  936                 // run2的當前元素拷貝到目標位置
 937                 a[dest--] = tmp[cursor2--];  938                 if (--len2 == 1)  939                     break outer;  940 
 941                 // 找到run2中大於等於run1當前元素的元素的位置索引好比K2, 則k2以後的全部元素大於run1, run2中的剩餘元素
 942                 count2 = len2 - gallopLeft(a[cursor1], tmp, tmpBase, len2, len2 - 1, c);  943                 if (count2 != 0) {  944                     dest -= count2;  945                     cursor2 -= count2;  946                     len2 -= count2;  947                     System.arraycopy(tmp, cursor2 + 1, a, dest + 1, count2);  948                     if (len2 <= 1)  // len2 == 1 || len2 == 0
 949                         break outer;  950  }  951                 // 拷貝run1的當前元素到目標位置, 由於a[cursior1]大於等於run2中的剩餘元素
 952                 a[dest--] = a[cursor1--];  953                 if (--len1 == 0)  954                     break outer;  955                 minGallop--;  956             } while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP);  957             if (minGallop < 0)  958                 minGallop = 0;  959             minGallop += 2;  // Penalize for leaving gallop mode
 960         }  // End of "outer" loop
 961         this.minGallop = minGallop < 1 ? 1 : minGallop;  // Write back to field  962 
 963         // run2中只有一個元素
 964         if (len2 == 1) {  965             assert len1 > 0;  966             dest -= len1;  967             cursor1 -= len1;  968             // 拷貝run1中的全部元素到目標位置
 969             System.arraycopy(a, cursor1 + 1, a, dest + 1, len1);  970             // run2的最後一個元素放入第一個位置
 971             a[dest] = tmp[cursor2];  // Move first elt of run2 to front of merge
 972         } else if (len2 == 0) {  973             // 由於run2的第一個元素小於run1, run2中的全部元素, 所以run2不可能最後爲空
 974             throw new IllegalArgumentException(  975                 "Comparison method violates its general contract!");  976         } else {  977             assert len1 == 0;  978             assert len2 > 0;  979             // 拷貝run2中的剩餘元素
 980             System.arraycopy(tmp, tmpBase, a, dest - (len2 - 1), len2);  981  }  982  }  983 
 984     /**
 985  * Ensures that the external array tmp has at least the specified  986  * number of elements, increasing its size if necessary. The size  987  * increases exponentially to ensure amortized linear time complexity.  988  *  989  * @param minCapacity the minimum required capacity of the tmp array  990  * @return tmp, whether or not it grew  991      */
 992     private T[] ensureCapacity(int minCapacity) {  993         if (tmpLen < minCapacity) {  994             // Compute smallest power of 2 > minCapacity
 995             int newSize = minCapacity;  996             newSize |= newSize >> 1;  997             newSize |= newSize >> 2;  998             newSize |= newSize >> 4;  999             newSize |= newSize >> 8; 1000             newSize |= newSize >> 16; 1001             newSize++; 1002 
1003             if (newSize < 0) // Not bloody likely!
1004                 newSize = minCapacity; 1005             else
1006                 newSize = Math.min(newSize, a.length >>> 1); 1007 
1008             @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"}) 1009             T[] newArray = (T[])java.lang.reflect.Array.newInstance 1010  (a.getClass().getComponentType(), newSize); 1011             tmp = newArray; 1012             tmpLen = newSize; 1013             tmpBase = 0; 1014  } 1015         return tmp; 1016  } 1017 }
相關文章
相關標籤/搜索