在java中,collections.sort使用合并排序算法而不是快速排序。但是Arrays.sort使用快速排序。 (而且我不确定上述事实,但我在互联网上发现这个像CodeRanch这样的网站,如果他们不使用那个algoritjm请告诉我)
现在我知道两种算法的平均复杂度是相同的。唯一的事实是快速排序最差的是O(n ^ 2),但这并不常见。 我们并不关心当今世界的空间,因此合并排序不是就地算法并不重要。 但是我们关注稳定性,所以为什么我们对array.sort使用快速排序,因为它不是一个稳定的算法。是因为它只关心整数,但我不认为这是一个很好的理由。
答案 0 :(得分:7)
Arrays.sort
仅对原始数组使用双轴快速排序算法,其中稳定和不稳定排序算法之间没有区别。这通常被认为稍微快一点,但它不稳定,因此它仅用于稳定性无关的情况。
Arrays.sort
和Collections.sort
使用Timsort,它是一个执行稳定排序的mergesort变体。
答案 1 :(得分:2)
Arrays.sort
并没有真正使用常见的快速排序实现,javadoc指定:
排序算法是Vladimir的Dual-Pivot Quicksort Yaroslavskiy,Jon Bentley和Joshua Bloch。该算法提供 O(n log(n))在导致其他快速排序的许多数据集上的性能 降低到二次性能,通常比...更快 传统(单枢轴)Quicksort实现。
查看DualPivotQuicksort
中的排序算法;正如您在注释中看到的那样,根据给定的数组使用不同的排序算法。
对于Collections
排序方法,它会在收到的实现上调用sort
(在我验证的情况下)委托给Arrays.sort
。
答案 2 :(得分:2)
通过查看相关的Javadocs甚至是source code,可以轻松验证您的前提。首先,请注意Collections.sort(List<T>)
只是委托给Arrays.sort(Object[])
(source):
public static <T extends Comparable<? super T>> void sort(List<T> list) {
Object[] a = list.toArray();
Arrays.sort(a);
ListIterator<T> i = list.listIterator();
for (int j=0; j<a.length; j++) {
i.next();
i.set((T)a[j]);
}
}
所以这两个方法将具有相同的行为和运行时。如文档中所述,实现是TimSort,合并排序和插入排序混合。它保证稳定。因此,无论您有数组还是集合,排序对象的工作方式都是相同的。
您链接的文章指的是排序原始数组。关于原始数组需要做的假设较少,特别是根据定义,相等的基元是难以区分的。这意味着没有必要确保稳定的排序。你会注意到原始排序方法的文档,比如Arrays.sort(int[])
,没有提到这些排序方法的稳定性,因为这样的细节是没有意义的。稳定性仅在排序可能相同但不相同的数据时很重要。
答案 3 :(得分:0)
Arrays.sort将比Collections.sort略快,因为Collections.sort在内部调用Arrays.sort。 在处理基元时,稳定性是不相关的,因为相同值的基元可以重新排列而没有副作用。而Arrays.sort提供了额外的性能优势。因此,对于原始数组,Arrays.sort将是首选。