为什么呢?是更快还是更有效?
对于具有一个核心的系统,我们可以使用quicksort。我们应该在具有两个内核,四个内核或八个内核的系统上使用什么?
答案 0 :(得分:34)
Quicksort具有完全就位的优势,因此它不需要任何额外的存储,而mergesort( 实际上由Arrays.sort()
用于对象数组)和其他(所有?)保证O(n * log n)算法至少需要一个完整的数组副本。对于对非常大的原始数组进行排序的程序,这意味着可能会使整体内存使用量翻倍。
答案 1 :(得分:18)
答案在Jon L. Bentley和M. Douglas McIlroy的“Engineering a Sort Function”中,排序函数引用。
为了获得更好的qsort,我们发现1983年在Berkeley编写的qsort会在包含少量元素重复多次的数组上消耗二次时间 - 特别是随机零和1的数组。事实上,在十几个不同的Unix库中,我们发现没有qsort不能轻易被驱动到二次行为;所有这些都来自第七版或1983年的伯克利函数......无法找到足够好的qsort,我们打算建立一个更好的。该算法应该避免合理输入的极端减速,并且应该在“随机”输入上快速。它在数据空间和代码空间中也应该是高效的。排序不一定稳定;它的规范不保证保持相等元素的顺序。
由于Java是在20世纪90年代初创建的,所以替代品是heapsort和mergesort。 Mergesort不太理想,因为它需要额外的存储空间。 Heapsort具有更好的最坏情况性能(O(n log n)
与O(n^2)
相比),但在实践中表现更慢。因此,如果您可以通过良好的启发式方法控制最坏情况的性能,那么可以采用优化的快速排序方式。
Java 7正在转向Timsort,它是在1993年发明的(2002年在Python中实现),并且具有O(n log n)
的最差情况并且是稳定的类型。
答案 2 :(得分:14)
Quicksort具有O(n log n)平均值和O(n ^ 2)最差情况性能,这是排序算法可能的最佳“平均情况”,还有其他排序算法具有此性能,但快速排序趋势比大多数人表现更好。
答案 3 :(得分:10)
这是调整快速排序。如果您真的感兴趣,可以阅读文档中提到的材料。
排序算法是一个经过调整的快速排序,改编自Jon L. Bentley和M. Douglas McIlroy的“Engineering a Sort Function”,Software-Practice and Experience,Vol。 23(11)P。1249-1265(1993年11月)。
这里有一点解释 - 调整后的版本在许多数据集上给出了n * log(n):
此算法在许多数据集上提供n * log(n)性能,导致其他快捷方式降级为二次性能
答案 4 :(得分:3)
与Quicksort相比,Mergesort的比较次数较少,但移动元素的数量较多。
在Java中,元素比较是昂贵的,但移动元素很便宜。因此,Mergesort在标准Java库中用于通用排序
在C ++中,复制对象可能很昂贵,而比较对象通常相对便宜。因此,quicksort是C ++库中常用的排序例程。
参考:http://www.cs.txstate.edu/~rp44/cs3358_092/Lectures/qsort.ppt
答案 5 :(得分:1)
首先,Arrays.sort不仅仅使用快速排序,它使用多个算法java1.6以后
请参阅以下来自Arrays类的代码
/ ** *将指定的数组按数字升序排序。 * *
实施说明:排序算法是Dual-Pivot Quicksort *由Vladimir Yaroslavskiy,Jon Bentley和Joshua Bloch撰写。这个算法 *在许多导致其他数据集的数据集上提供O(n log(n))性能 *快速降级为二次性能,通常是 *比传统(单枢轴)Quicksort实现更快。 * * @param要排序的数组 * / public static void sort(int [] a){ DualPivotQuicksort.sort(一); }
DualPivotQuicksort.sort(a); // This uses 5 algorithms internally depending upon dataset size
do checkout the source code of Arrays class.
在java 1.6之前我认为它使用三种算法快速排序原始类型,例如int和mergesort用于对象,当快速排序执行它开始堆排序时,请参阅此处了解更多详细信息 http://cafe.elharo.com/programming/java-programming/why-java-util-arrays-uses-two-sorting-algorithms
答案 6 :(得分:0)
Quicksort平均O(n log(n))
平均速度最快,因此Sun可能会将其作为一个很好的指标。
答案 7 :(得分:0)
QuickSort是一种常见的排序算法。它的速度相当快,除非要排序的数据已经是相反的顺序。它在太空中也很有效。
答案 8 :(得分:0)
这取决于你想做什么。正常快速排序的问题是,它有时可以是O(n²)。所以通常你可以使用堆排序,但大多数情况下快速排序更快。
然而,Arrays.sort(...)实现使用了“调整过的快速排序,改编自Jon L. Bentley和M. Douglas McIlroy [...]”(根据JavaDoc文档)。该算法具有一些优化的内置,使其能够在O(n * log(n))上工作,其中普通的快速排序将使用O(n²)。
Arrays.sort算法也会一遍又一遍地进行测试,你可以确定它是有效的并且是无错误的(虽然这不能得到保证。)
iuiz
答案 9 :(得分:0)
Arrays.sort()使用多种排序算法,具体取决于数组中的大小和元素。
所以在实践中我们看到快速排序对于大型基元数组来说非常快,但是当它需要适应部分排序的数组时,当对象之间的比较缓慢,稳定排序等等时会有一些陷阱。
答案 10 :(得分:0)
自从该线程的最后答案以来已经有一段时间了,这里有一些更新...
java研究这些算法时,取决于复杂性及其与数组大小的相关性以及概率,并且取决于度量和基准。
根据JAVA JDK 1.8 DOCS,它在不选择算法的情况下自我说明 根据一些阈值,只能选择一个,但最多四个...
/**
* If the length of an array to be sorted is less than this
* constant, Quicksort is used in preference to merge sort.
*/
private static final int QUICKSORT_THRESHOLD = 286;
/**
* If the length of an array to be sorted is less than this
* constant, insertion sort is used in preference to Quicksort.
*/
private static final int INSERTION_SORT_THRESHOLD = 47;
/**
* If the length of a byte array to be sorted is greater than this
* constant, counting sort is used in preference to insertion sort.
*/
private static final int COUNTING_SORT_THRESHOLD_FOR_BYTE = 29;
/**
* If the length of a short or char array to be sorted is greater
* than this constant, counting sort is used in preference to Quicksort.
*/
private static final int COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR = 3200;
该事件演变为使用并行排序 Sorting in Java
Java 8 带有一个新的API – parallelSort –具有与Arrays.sort()
API相似的签名:
@Test
public void givenIntArray_whenUsingParallelSort_thenArraySorted() {
Arrays.parallelSort(toSort);
assertTrue(Arrays.equals(toSort, sortedInts));
}
在 parallelSort ()的幕后,它将数组分成不同的子数组(根据parallelSort算法中的粒度)。每个子数组都在不同的线程中用 Arrays.sort ()进行排序,以便可以并行执行排序并最终将其合并为一个排序的数组。
请注意,ForJoin公共池用于执行这些并行任务,然后合并结果。
Arrays.parallelSort的结果将与Array.sort相同,这只是利用多线程的问题。
最后,Arrays.parallelSort中也有API Arrays.sort的类似变体:
Arrays.parallelSort (int [] a, int fromIndex, int toIndex);
摘要: 因此,随着Java API随硬件和软件的发展而发展 多线程和调优在这里和那里有更多用途 在阈值和算法上。
答案 11 :(得分:0)
Arrays.sort()不使用快速排序。 Java 7使用的TimSort是合并排序和插入排序的组合。 当元素数量更多时,Java 8使用并行排序,并使用多个线程进行排序。否则它会使用TimSort。
因此,最坏情况下的时间复杂度始终为O(nlogn)