簡介:
在1.8以前的版本中對此方法進行了重寫,若是還須要使用以前的排序算法,須要加上系統屬性java.util.Arrays.useLegacyMergeSort=true,以前的排序使用優化後的歸併排序,在1.8中使用TimSort算法來進行排序,TimSort算法是由Tim Peters在2002提出並首先實如今了phtyon中,是結合了合併排序(merge sort)和插入排序(insertion sort)的一種高效穩定的算法。算法原理看這裏 https://blog.csdn.net/yangzhongblog/article/details/8184707java
Arrays.sort(Object[] a)分析
一、 方法聲明算法
/** * 根據Comparable的天然排序將給定數組升序排序。全部元素必須實現Comparable 接口 * 並且,全部元素能相互比較,否則可能會拋出ClassCastException異常 * * 此排序確保是穩定的,若是兩個元素e1.equals(e2),那麼他們不會被再次排序 * * 該實現是一個穩定、自適應、重複的歸併排序,當給定數組是局部排序的數組時它的時間複雜度比 nlogn更小, * 然而當給定數組是隨機排序,它與傳統的歸併排序性能相同。若是給定數組大致有序,該算法只須要大概n次比較便可完成排序。 * * 該算法在輸入數組爲升序或降序時都能發揮優點,而且在該數組部分有序的狀況下也能發揮其優點, * 它能經過簡單鏈接便可很好的完成將多個數組進行合併 */ public static void sort(Object[] a) { //若是要兼容1.8以前的排序程序,在系統屬性中須要添加屬性,如:java -jar -Djava.Arrays.uselegacyMergeSort=true xx.jar if (LegacyMergeSort.userRequested) legacyMergeSort(a); else //真正的TimSort算法實如今ComparableTimSort中 ComparableTimSort.sort(a, 0, a.length, null, 0, 0); }
二、 ComparableTimSort.sort(Object[] a, int lo, int hi, Object[] work, int workBase, int workLen)分析數組
/** * 將數組指定範圍內的元素排序 * * [@param](https://my.oschina.net/u/2303379) a 被排序數組 * [@param](https://my.oschina.net/u/2303379) lo 排序開始元素index * [@param](https://my.oschina.net/u/2303379) hi 排序結束元素index,不包含此index * [@param](https://my.oschina.net/u/2303379) work a workspace array (slice) * [@param](https://my.oschina.net/u/2303379) workBase origin of usable space in work array * @param workLen usable size of work array * @since 1.8 */ 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; //對於只有0|1個元素的數組,不須要進行排序 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); //使用二叉插入排序對在initRunLen後的元素進行排序 binarySort(a, lo, hi, lo + initRunLen); 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. */ //構造ComparableTimSort對象 ComparableTimSort ts = new ComparableTimSort(a, work, workBase, workLen); //計算最小run的長度 int minRun = minRunLength(nRemaining); do { // Identify next run //計算當前排序的run的長度,若是爲遞減數組則翻轉 int runLen = countRunAndMakeAscending(a, lo, hi); // If run is short, extend to min(minRun, nRemaining) //若是當前run的長度小於minRun,則進行擴展,在擴展過程當中使用二叉排序來排序擴展的的元素 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 //將此run放入棧中 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; //保證最後的run都被合併 ts.mergeForceCollapse(); assert ts.stackSize == 1; }