一般排序算法都是有关数组的排序,而且使用的是随机访问方式。但是对列表进行访问的效率很低。实际上,可以使用归并排序对列表进行高效的排序。然后Java的实现却是:直接将所有元素转入一个数组,对数组进行排序,然后再将排序后的序列复制回列表。
以下是Collections.class
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 /** 2 * Sorts the specified list according to the order induced by the 3 * specified comparator. All elements in the list must be <i>mutually 4 * comparable</i> using the specified comparator (that is, 5 * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException} 6 * for any elements {@code e1} and {@code e2} in the list). 7 * 8 * <p>This sort is guaranteed to be <i>stable</i>: equal elements will 9 * not be reordered as a result of the sort. 10 * 11 * <p>The specified list must be modifiable, but need not be resizable. 12 * 13 * @implNote 14 * This implementation defers to the {@link List#sort(Comparator)} 15 * method using the specified list and comparator. 16 * 17 * @param <T> the class of the objects in the list 18 * @param list the list to be sorted. 19 * @param c the comparator to determine the order of the list. A 20 * {@code null} value indicates that the elements' <i>natural 21 * ordering</i> should be used. 22 * @throws ClassCastException if the list contains elements that are not 23 * <i>mutually comparable</i> using the specified comparator. 24 * @throws UnsupportedOperationException if the specified list's 25 * list-iterator does not support the {@code set} operation. 26 * @throws IllegalArgumentException (optional) if the comparator is 27 * found to violate the {@link Comparator} contract 28 * @see List#sort(Comparator) 29 */ 30 @SuppressWarnings({"unchecked", "rawtypes"}) 31 public static <T> void sort(List<T> list, Comparator<? super T> c) { 32 list.sort(c); 33 }
观察这段源码,我们可以发现:
1.排序是根据指定的比较器comparator对列表list进行排序。
2.排序是稳定的,即相同元素不会重新排序
Collections.class类中并没有给出排序的具体实现,而是调用了List.class中的实现,我们进入List.class中继续观察源码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 /** 2 * Sorts this list according to the order induced by the specified 3 * {@link Comparator}. 4 * 5 * <p>All elements in this list must be <i>mutually comparable</i> using the 6 * specified comparator (that is, {@code c.compare(e1, e2)} must not throw 7 * a {@code ClassCastException} for any elements {@code e1} and {@code e2} 8 * in the list). 9 * 10 * <p>If the specified comparator is {@code null} then all elements in this 11 * list must implement the {@link Comparable} interface and the elements' 12 * {@linkplain Comparable natural ordering} should be used. 13 * 14 * <p>This list must be modifiable, but need not be resizable. 15 * 16 * @implSpec 17 * The default implementation obtains an array containing all elements in 18 * this list, sorts the array, and iterates over this list resetting each 19 * element from the corresponding position in the array. (This avoids the 20 * n<sup>2</sup> log(n) performance that would result from attempting 21 * to sort a linked list in place.) 22 * 23 * @implNote 24 * This implementation is a stable, adaptive, iterative mergesort that 25 * requires far fewer than n lg(n) comparisons when the input array is 26 * partially sorted, while offering the performance of a traditional 27 * mergesort when the input array is randomly ordered. If the input array 28 * is nearly sorted, the implementation requires approximately n 29 * comparisons. Temporary storage requirements vary from a small constant 30 * for nearly sorted input arrays to n/2 object references for randomly 31 * ordered input arrays. 32 * 33 * <p>The implementation takes equal advantage of ascending and 34 * descending order in its input array, and can take advantage of 35 * ascending and descending order in different parts of the same 36 * input array. It is well-suited to merging two or more sorted arrays: 37 * simply concatenate the arrays and sort the resulting array. 38 * 39 * <p>The implementation was adapted from Tim Peters's list sort for Python 40 * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt"> 41 * TimSort</a>). It uses techniques from Peter McIlroy's "Optimistic 42 * Sorting and Information Theoretic Complexity", in Proceedings of the 43 * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, 44 * January 1993. 45 * 46 * @param c the {@code Comparator} used to compare list elements. 47 * A {@code null} value indicates that the elements' 48 * {@linkplain Comparable natural ordering} should be used 49 * @throws ClassCastException if the list contains elements that are not 50 * <i>mutually comparable</i> using the specified comparator 51 * @throws UnsupportedOperationException if the list's list-iterator does 52 * not support the {@code set} operation 53 * @throws IllegalArgumentException 54 * (<a href="Collection.html#optional-restrictions">optional</a>) 55 * if the comparator is found to violate the {@link Comparator} 56 * contract 57 * @since 1.8 58 */ 59 @SuppressWarnings({"unchecked", "rawtypes"}) 60 default void sort(Comparator<? super E> c) { 61 Object[] a = this.toArray(); 62 Arrays.sort(a, (Comparator) c); 63 ListIterator<E> i = this.listIterator(); 64 for (Object e : a) { 65 i.next(); 66 i.set((E) e); 67 } 68 }
观察这段源码,我们可以发现:
1.排序过程是将列表赋值给一个数组,然后调用数组的排序方法对数组排序,然后迭代列表,赋值相对应的数组值。这样可以避免对链表排序造成的n^2logn的时间复杂度。
2.此实现是一个稳定的。当输入数组被部分排序时,它需要远远少于n lg(n)次的比较,如果输入数组是随机排序的,性能和归并排序一样。 如果输入数组几乎已排序,则实现需要大约n次比较。
List.class类中没有给出排序的细节实现,而是调用了Arrays.class中的实现,我们进入Arrays.class中继续观察源码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 /** 2 * Sorts the specified array of objects according to the order induced by 3 * the specified comparator. All elements in the array must be 4 * <i>mutually comparable</i> by the specified comparator (that is, 5 * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException} 6 * for any elements {@code e1} and {@code e2} in the array). 7 * 8 * <p>This sort is guaranteed to be <i>stable</i>: equal elements will 9 * not be reordered as a result of the sort. 10 * 11 * <p>Implementation note: This implementation is a stable, adaptive, 12 * iterative mergesort that requires far fewer than n lg(n) comparisons 13 * when the input array is partially sorted, while offering the 14 * performance of a traditional mergesort when the input array is 15 * randomly ordered. If the input array is nearly sorted, the 16 * implementation requires approximately n comparisons. Temporary 17 * storage requirements vary from a small constant for nearly sorted 18 * input arrays to n/2 object references for randomly ordered input 19 * arrays. 20 * 21 * <p>The implementation takes equal advantage of ascending and 22 * descending order in its input array, and can take advantage of 23 * ascending and descending order in different parts of the the same 24 * input array. It is well-suited to merging two or more sorted arrays: 25 * simply concatenate the arrays and sort the resulting array. 26 * 27 * <p>The implementation was adapted from Tim Peters's list sort for Python 28 * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt"> 29 * TimSort</a>). It uses techniques from Peter McIlroy's "Optimistic 30 * Sorting and Information Theoretic Complexity", in Proceedings of the 31 * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, 32 * January 1993. 33 * 34 * @param <T> the class of the objects to be sorted 35 * @param a the array to be sorted 36 * @param c the comparator to determine the order of the array. A 37 * {@code null} value indicates that the elements' 38 * {@linkplain Comparable natural ordering} should be used. 39 * @throws ClassCastException if the array contains elements that are 40 * not <i>mutually comparable</i> using the specified comparator 41 * @throws IllegalArgumentException (optional) if the comparator is 42 * found to violate the {@link Comparator} contract 43 */ 44 public static <T> void sort(T[] a, Comparator<? super T> c) { 45 if (c == null) { 46 sort(a); 47 } else { 48 if (LegacyMergeSort.userRequested) 49 legacyMergeSort(a, c); 50 else 51 TimSort.sort(a, 0, a.length, c, null, 0, 0); 52 } 53 } 54 55 /** To be removed in a future release. */ 56 private static <T> void legacyMergeSort(T[] a, Comparator<? super T> c) { 57 T[] aux = a.clone(); 58 if (c==null) 59 mergeSort(aux, a, 0, a.length, 0); 60 else 61 mergeSort(aux, a, 0, a.length, 0, c); 62 }
观察这段源码,我们可以发现:
1.排序是稳定的。
2.如果用户指定使用传统的归并排序,则对数组进行归并排序,如果没有指定,则使用TimSort。
下面是源码中给出的归并排序的源码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 /** 2 * Tuning parameter: list size at or below which insertion sort will be 3 * used in preference to mergesort. 4 * To be removed in a future release. 5 */ 6 private static final int INSERTIONSORT_THRESHOLD = 7; 7 8 /** 9 * Src is the source array that starts at index 0 10 * Dest is the (possibly larger) array destination with a possible offset 11 * low is the index in dest to start sorting 12 * high is the end index in dest to end sorting 13 * off is the offset to generate corresponding low, high in src 14 * To be removed in a future release. 15 */ 16 @SuppressWarnings({"unchecked", "rawtypes"}) 17 private static void mergeSort(Object[] src, 18 Object[] dest, 19 int low, 20 int high, 21 int off) { 22 int length = high - low; 23 24 // Insertion sort on smallest arrays 25 if (length < INSERTIONSORT_THRESHOLD) { 26 for (int i=low; i<high; i++) 27 for (int j=i; j>low && 28 ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--) 29 swap(dest, j, j-1); 30 return; 31 } 32 33 // Recursively sort halves of dest into src 34 int destLow = low; 35 int destHigh = high; 36 low += off; 37 high += off; 38 int mid = (low + high) >>> 1; 39 mergeSort(dest, src, low, mid, -off); 40 mergeSort(dest, src, mid, high, -off); 41 42 // If list is already sorted, just copy from src to dest. This is an 43 // optimization that results in faster sorts for nearly ordered lists. 44 if (((Comparable)src[mid-1]).compareTo(src[mid]) <= 0) { 45 System.arraycopy(src, low, dest, destLow, length); 46 return; 47 } 48 49 // Merge sorted halves (now in src) into dest 50 for(int i = destLow, p = low, q = mid; i < destHigh; i++) { 51 if (q >= high || p < mid && ((Comparable)src[p]).compareTo(src[q])<=0) 52 dest[i] = src[p++]; 53 else 54 dest[i] = src[q++]; 55 } 56 } 57 58 /** 59 * Swaps x[a] with x[b]. 60 */ 61 private static void swap(Object[] x, int a, int b) { 62 Object t = x[a]; 63 x[a] = x[b]; 64 x[b] = t; 65 }
观察这段源码,我们可以发现:设置一个阈值为7,如果待排序数组的长度小于7,则使用插入排序,如果待排序数组的长度大于等于7,则使用归并排序。
TimSort待更。。。