jdk自带排序学习,比如我们写一个排序代码
List score = new ArrayList();score.add(1);score.add(12);score.add(45);score.add(67);Collections.sort(score);
来看一下sort的实现
/*** Sorts the specified list into ascending order, according to the* {@linkplain Comparable natural ordering} of its elements.* All elements in the list must implement the {@link Comparable}* interface. Furthermore, all elements in the list must be* <i>mutually comparable</i> (that is, {@code e1.compareTo(e2)}* must not throw a {@code ClassCastException} for any elements* {@code e1} and {@code e2} in the list).** <p>This sort is guaranteed to be <i>stable</i>: equal elements will* not be reordered as a result of the sort.** <p>The specified list must be modifiable, but need not be resizable.** @implNote* This implementation defers to the {@link List#sort(Comparator)}* method using the specified list and a {@code null} comparator.** @param <T> the class of the objects in the list* @param list the list to be sorted.* @throws ClassCastException if the list contains elements that are not* <i>mutually comparable</i> (for example, strings and integers).* @throws UnsupportedOperationException if the specified list's* list-iterator does not support the {@code set} operation.* @throws IllegalArgumentException (optional) if the implementation* detects that the natural ordering of the list elements is* found to violate the {@link Comparable} contract* @see List#sort(Comparator)*/@SuppressWarnings("unchecked")public static <T extends Comparable<? super T>> void sort(List<T> list) {list.sort(null);}
继续跟进
/*** Sorts this list according to the order induced by the specified* {@link Comparator}.** <p>All elements in this list must be <i>mutually comparable</i> using the* specified comparator (that is, {@code c.compare(e1, e2)} must not throw* a {@code ClassCastException} for any elements {@code e1} and {@code e2}* in the list).** <p>If the specified comparator is {@code null} then all elements in this* list must implement the {@link Comparable} interface and the elements'* {@linkplain Comparable natural ordering} should be used.** <p>This list must be modifiable, but need not be resizable.** @implSpec* The default implementation obtains an array containing all elements in* this list, sorts the array, and iterates over this list resetting each* element from the corresponding position in the array. (This avoids the* n<sup>2</sup> log(n) performance that would result from attempting* to sort a linked list in place.)** @implNote* This implementation is a stable, adaptive, iterative mergesort that* requires far fewer than n lg(n) comparisons when the input array is* partially sorted, while offering the performance of a traditional* mergesort when the input array is randomly ordered. If the input array* is nearly sorted, the implementation requires approximately n* comparisons. Temporary storage requirements vary from a small constant* for nearly sorted input arrays to n/2 object references for randomly* ordered input arrays.** <p>The implementation takes equal advantage of ascending and* descending order in its input array, and can take advantage of* ascending and descending order in different parts of the same* input array. It is well-suited to merging two or more sorted arrays:* simply concatenate the arrays and sort the resulting array.** <p>The implementation was adapted from Tim Peters's list sort for Python* (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt">* TimSort</a>). It uses techniques from Peter McIlroy's "Optimistic* Sorting and Information Theoretic Complexity", in Proceedings of the* Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474,* January 1993.** @param c the {@code Comparator} used to compare list elements.* A {@code null} value indicates that the elements'* {@linkplain Comparable natural ordering} should be used* @throws ClassCastException if the list contains elements that are not* <i>mutually comparable</i> using the specified comparator* @throws UnsupportedOperationException if the list's list-iterator does* not support the {@code set} operation* @throws IllegalArgumentException* (<a href="Collection.html#optional-restrictions">optional</a>)* if the comparator is found to violate the {@link Comparator}* contract* @since 1.8*/@SuppressWarnings({"unchecked", "rawtypes"})default void sort(Comparator<? super E> c) {Object[] a = this.toArray();Arrays.sort(a, (Comparator) c);ListIterator<E> i = this.listIterator();for (Object e : a) {i.next();i.set((E) e);}}
/*** Sorts the specified array of objects according to the order induced by* the specified comparator. All elements in the array must be* <i>mutually comparable</i> by the specified comparator (that is,* {@code c.compare(e1, e2)} must not throw a {@code ClassCastException}* for any elements {@code e1} and {@code e2} in the array).** <p>This sort is guaranteed to be <i>stable</i>: equal elements will* not be reordered as a result of the sort.** <p>Implementation note: This implementation is a stable, adaptive,* iterative mergesort that requires far fewer than n lg(n) comparisons* when the input array is partially sorted, while offering the* performance of a traditional mergesort when the input array is* randomly ordered. If the input array is nearly sorted, the* implementation requires approximately n comparisons. Temporary* storage requirements vary from a small constant for nearly sorted* input arrays to n/2 object references for randomly ordered input* arrays.** <p>The implementation takes equal advantage of ascending and* descending order in its input array, and can take advantage of* ascending and descending order in different parts of the the same* input array. It is well-suited to merging two or more sorted arrays:* simply concatenate the arrays and sort the resulting array.** <p>The implementation was adapted from Tim Peters's list sort for Python* (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt">* TimSort</a>). It uses techniques from Peter McIlroy's "Optimistic* Sorting and Information Theoretic Complexity", in Proceedings of the* Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474,* January 1993.** @param <T> the class of the objects to be sorted* @param a the array to be sorted* @param c the comparator to determine the order of the array. A* {@code null} value indicates that the elements'* {@linkplain Comparable natural ordering} should be used.* @throws ClassCastException if the array contains elements that are* not <i>mutually comparable</i> using the specified comparator* @throws IllegalArgumentException (optional) if the comparator is* found to violate the {@link Comparator} contract*/public static <T> void sort(T[] a, Comparator<? super T> c) {if (c == null) {sort(a);} else {if (LegacyMergeSort.userRequested)legacyMergeSort(a, c);elseTimSort.sort(a, 0, a.length, c, null, 0, 0);}}
如果没有自定义排序就执行默认排序
/*** Sorts the specified array of objects into ascending order, according* to the {@linkplain Comparable natural ordering} of its elements.* All elements in the array must implement the {@link Comparable}* interface. Furthermore, all elements in the array must be* <i>mutually comparable</i> (that is, {@code e1.compareTo(e2)} must* not throw a {@code ClassCastException} for any elements {@code e1}* and {@code e2} in the array).** <p>This sort is guaranteed to be <i>stable</i>: equal elements will* not be reordered as a result of the sort.** <p>Implementation note: This implementation is a stable, adaptive,* iterative mergesort that requires far fewer than n lg(n) comparisons* when the input array is partially sorted, while offering the* performance of a traditional mergesort when the input array is* randomly ordered. If the input array is nearly sorted, the* implementation requires approximately n comparisons. Temporary* storage requirements vary from a small constant for nearly sorted* input arrays to n/2 object references for randomly ordered input* arrays.** <p>The implementation takes equal advantage of ascending and* descending order in its input array, and can take advantage of* ascending and descending order in different parts of the the same* input array. It is well-suited to merging two or more sorted arrays:* simply concatenate the arrays and sort the resulting array.** <p>The implementation was adapted from Tim Peters's list sort for Python* (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt">* TimSort</a>). It uses techniques from Peter McIlroy's "Optimistic* Sorting and Information Theoretic Complexity", in Proceedings of the* Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474,* January 1993.** @param a the array to be sorted* @throws ClassCastException if the array contains elements that are not* <i>mutually comparable</i> (for example, strings and integers)* @throws IllegalArgumentException (optional) if the natural* ordering of the array elements is found to violate the* {@link Comparable} contract*/public static void sort(Object[] a) {if (LegacyMergeSort.userRequested)legacyMergeSort(a);elseComparableTimSort.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);}
legacyMergeSort 归并排序默认关闭的,重点关注 ComparableTimSort.sort
/*** Sorts the given range, using the given workspace array slice* for temp storage when possible. This method is designed to be* invoked from public methods (in class Arrays) after performing* any necessary array bounds checks and expanding parameters into* the required forms.** @param a the array to be sorted* @param lo the index of the first element, inclusive, to be sorted* @param hi the index of the last element, exclusive, to be sorted* @param work a workspace array (slice)* @param 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;if (nRemaining < 2)return; // Arrays of size 0 and 1 are always sorted// If array is small, do a "mini-TimSort" with no mergesif (nRemaining < MIN_MERGE) {int initRunLen = countRunAndMakeAscending(a, lo, hi);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 ts = new ComparableTimSort(a, work, workBase, workLen);int minRun = minRunLength(nRemaining);do {// Identify next runint 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 mergets.pushRun(lo, runLen);ts.mergeCollapse();// Advance to find next runlo += runLen;nRemaining -= runLen;} while (nRemaining != 0);// Merge all remaining runs to complete sortassert lo == hi;ts.mergeForceCollapse();assert ts.stackSize == 1;}
如果小于 private static final int MIN_MERGE = 32;大小就进行折半插入排序,如果大于32进行
TimSort排序
/*** Sorts the given range, using the given workspace array slice* for temp storage when possible. This method is designed to be* invoked from public methods (in class Arrays) after performing* any necessary array bounds checks and expanding parameters into* the required forms.** @param a the array to be sorted* @param lo the index of the first element, inclusive, to be sorted* @param hi the index of the last element, exclusive, to be sorted* @param work a workspace array (slice)* @param 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;if (nRemaining < 2)return; // Arrays of size 0 and 1 are always sorted// If array is small, do a "mini-TimSort" with no mergesif (nRemaining < MIN_MERGE) {int initRunLen = countRunAndMakeAscending(a, lo, hi);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 ts = new ComparableTimSort(a, work, workBase, workLen);int minRun = minRunLength(nRemaining);do {// Identify next runint 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 mergets.pushRun(lo, runLen);ts.mergeCollapse();// Advance to find next runlo += runLen;nRemaining -= runLen;} while (nRemaining != 0);// Merge all remaining runs to complete sortassert lo == hi;ts.mergeForceCollapse();assert ts.stackSize == 1;}
Timsort是一个自适应的、混合的、稳定的排序算法,是由Tim Peter于2002年发明的,最早应用在Python中,现在广泛应用于Python、Java、Android 等语言与平台中,作为基础的排序算法使用。其中Java语言的Collection.sort在JDK1.6使用的是普通的归并排序,归并排序虽然时间复杂度低,但是空间复杂度要求较高,所以从JDK1.7开始就更改为了TimSort算法。
Timsort 的时间复杂度是 O(n log n),与归并排序的时间复杂度相同,那它的优势是啥呢,实际上可以认为TimSort排序算法是归并排序算法的优化版,从它的三个特征就可以看出,第二个特征“混合的”,没错,它不单纯是一种算法,而是融合了归并算法和二分插入排序算法的精髓,因此能够在排序性能上表现优异。
总结:排序->自定义接口实现排序->归并排序->折半插入排序->TImSort
欢迎指正交流