从源码看Java内置的排序sort()函数

一般排序算法都是有关数组的排序,而且使用的是随机访问方式。但是对列表进行访问的效率很低。实际上,可以使用归并排序对列表进行高效的排序。然后Java的实现却是:直接将所有元素转入一个数组,对数组进行排序,然后再将排序后的序列复制回列表。

以下是Collections.class

 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     }
View Code

 观察这段源码,我们可以发现:

1.排序是根据指定的比较器comparator对列表list进行排序。

2.排序是稳定的,即相同元素不会重新排序

Collections.class类中并没有给出排序的具体实现,而是调用了List.class中的实现,我们进入List.class中继续观察源码:

 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     }
View Code

 观察这段源码,我们可以发现:

1.排序过程是将列表赋值给一个数组,然后调用数组的排序方法对数组排序,然后迭代列表,赋值相对应的数组值。这样可以避免对链表排序造成的n^2logn的时间复杂度。

2.此实现是一个稳定的。当输入数组被部分排序时,它需要远远少于n lg(n)次的比较,如果输入数组是随机排序的,性能和归并排序一样。 如果输入数组几乎已排序,则实现需要大约n次比较。 

List.class类中没有给出排序的细节实现,而是调用了Arrays.class中的实现,我们进入Arrays.class中继续观察源码:

 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     }
View Code

观察这段源码,我们可以发现:

1.排序是稳定的。

2.如果用户指定使用传统的归并排序,则对数组进行归并排序,如果没有指定,则使用TimSort。

下面是源码中给出的归并排序的源码:

 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     }
View Code

  观察这段源码,我们可以发现:设置一个阈值为7,如果待排序数组的长度小于7,则使用插入排序,如果待排序数组的长度大于等于7,则使用归并排序。

TimSort待更。。。

转载于:https://www.cnblogs.com/code4her/p/9514530.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值