Java 为什么Arrays.sort是快速排序算法,为什么不是另一种排序算法?
为什么??是更快还是更高效Java 为什么Arrays.sort是快速排序算法,为什么不是另一种排序算法?,java,algorithm,Java,Algorithm,为什么??是更快还是更高效 对于具有一个核心的系统,我们可以使用快速排序。在具有两个核、四个核或八个核的系统上,我们应该使用什么呢?快速排序平均速度最快O(n log(n)),因此Sun可能将其用作一个很好的指标。快速排序是一种常见的排序算法。它相当快,除非要排序的数据已经是逆序的。它在空间上也很有效。快速排序具有O(n log n)平均和O(n^2)最坏情况的性能,这是排序算法可以达到的最佳“平均情况”,还有其他排序算法具有这种性能,但快速排序往往比大多数排序算法的性能更好 请参阅:这是一个经
对于具有一个核心的系统,我们可以使用快速排序。在具有两个核、四个核或八个核的系统上,我们应该使用什么呢?快速排序平均速度最快
O(n log(n))
,因此Sun可能将其用作一个很好的指标。快速排序是一种常见的排序算法。它相当快,除非要排序的数据已经是逆序的。它在空间上也很有效。快速排序具有O(n log n)平均和O(n^2)最坏情况的性能,这是排序算法可以达到的最佳“平均情况”,还有其他排序算法具有这种性能,但快速排序往往比大多数排序算法的性能更好
请参阅:这是一个经过优化的快速排序。如果你真的感兴趣,你可以阅读文档中提到的材料
排序算法是一种经过调整的快速排序算法,改编自Jon L.Bentley和M.Douglas McIlroy的“工程排序功能”,软件实践与经验,第23卷(11)第1249-1265页(1993年11月)
这里有一点解释-调整后的版本在许多数据集上给出了n*log(n):
该算法在许多数据集上提供n*log(n)性能,这些数据集会导致其他快速排序降级为二次性能
快速排序的优点是完全到位,因此它不需要任何额外的存储,而mergesort(实际上由
Arrays.sort()
用于对象数组)和其他(all?)保证的O(n*logn)算法需要至少一个完整的数组副本。对于对非常大的基元数组进行排序的程序,这意味着总内存使用量可能会翻倍。这取决于您想做什么。普通快速排序的问题是,它有时可能是O(n²)。所以通常可以使用堆排序,但大多数情况下,快速排序速度更快
然而,Arrays.sort(…)实现使用了“调优的快速排序,改编自Jon L.Bentley和M.Douglas McIlroy[…]”(根据JavaDoc文档)。该算法有一些内置优化,使其能够在O(n*log(n))上工作,而普通的快速排序将使用O(n²)
此外,Arrays.sort算法经过反复测试,您可以确保它工作正常且无错误(尽管这无法保证)
iuiz答案是Jon L.Bentley和M.Douglas McIlroy的,排序函数引用了他们的答案 为了寻找更好的qsort,我们发现1983年在伯克利编写的qsort会在包含一些元素的数组上消耗二次时间,这些元素在特定的随机0和1数组中重复多次。事实上,在十几个不同的Unix库中,我们没有发现不容易被驱动为二次行为的qsort;所有这些都来自第七版或1983年伯克利函数 由于找不到足够好的qsort,我们开始建造一个更好的qsort。该算法应避免在合理的输入上出现极端减速,并且在“随机”输入上应快速。它在数据空间和代码空间也应该是高效的。种类不必是稳定的;它的规范不能保证保持相等元素的顺序 替代方案是heapsort和mergesort,因为Java是在20世纪90年代初创建的。Mergesort不太理想,因为它需要额外的存储空间。Heapsort在最坏情况下的性能(与
O(n^2)
相比,O(n log n)
)更好,但在实践中执行得更慢。因此,如果您可以通过良好的启发式方法控制最坏情况下的性能,那么优化的快速排序就是一条出路
Java 7正在切换到,它是1993年发明的(2002年在Python中实现),最坏的性能是
O(n log n)
,是一种稳定的排序。与Quicksort相比,Mergesort的比较次数更少,但移动元素的数量更多
在Java中,元素比较很昂贵,但移动元素很便宜。因此,在标准Java库中使用Mergesort进行通用排序
在C++中,复制对象可能比较昂贵,而比较对象通常比较便宜。因此,QuaseS排序是C++库常用的排序例程。
ref:首先,array.sort不仅使用快速排序,它还使用java1.6以后的多种算法 请参阅下面来自Arrays类的代码 /** *将指定数组按升序进行排序。 * *实施说明:排序算法是一种双枢轴快速排序 *弗拉基米尔·雅罗斯拉夫斯基、乔恩·本特利和约书亚·布洛赫。该算法 *在许多导致其他问题的数据集上提供O(n log(n))性能 *快速排序将降级为二次性能,通常是 *比传统(单轴)快速排序实现更快。 * *@param a要排序的数组 */ 公共静态无效排序(int[]a){ 双数据透视快速排序。排序(a); } 在Java1.6之前,我认为它对基本类型使用了三种算法QuickSort,例如对象的int和mergesort,当QuickSort执行它时,请参阅此处了解更多详细信息 根据数组中的大小和元素使用多种排序算法
- 小数组的插入排序
- 主要排序数组的合并排序
- 高度调整和适应性的双支点和单支点快速排序,适用于所有其他内容
因此,在实践中,我们看到快速排序对于大型原语数组来说非常快,但当它需要适应部分排序的数组、对象之间的比较缓慢、用于稳定排序等时,它会有一些缺陷。自从上一次回答这个问题已经有一段时间了,下面是一些更新 它取决于复杂度及其与数组大小的相关性,以及java重新生成时的概率
DualPivotQuicksort.sort(a); // This uses 5 algorithms internally depending upon dataset size
do checkout the source code of Arrays class.
/**
* 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;
@Test
public void givenIntArray_whenUsingParallelSort_thenArraySorted() {
Arrays.parallelSort(toSort);
assertTrue(Arrays.equals(toSort, sortedInts));
}
Arrays.parallelSort (int [] a, int fromIndex, int toIndex);