Java为什么不对基元使用基数排序?


12

java.util.Arrays.sort(/* int[], char[], short[], byte[], boolean[] */) 被实现为“优化的快速排序”,而不是基数排序。

我前一阵子做了速度比较,使用n> 10000之类的东西,基数排序总是更快。为什么?

Answers:


17

我会推测:

  • Array.sort被实现为quicksort,因为quicksort可以在给定比较器的情况下在适当的时间内对任何内容进行排序。
  • 排序10000个条目的列表并不常见。访问10000个或更多元素的数据结构是很常见的。如果您需要保持顺序,那么平衡的搜索树通常是比每次需要最小元素时对整个数组进行排序更好的方法。
  • 尽管大学可能会教给原语排序并不常见。

关键是,这不是一个常见的用例,它的优化需要在标准库中进行。如果您编写的应用程序存在性能问题,那么您可以通过分析确定对10000+个int数组进行排序实际上是瓶颈,那么您不妨手动编写排序或在第一遍重新考虑数据结构的选择地点。


不确定100%,但是我认为现在在某些情况下使用TimSort。
Martijn Verburg 2012年

1
但是没有Array.sort,有多个Array.sorts,问题是关于数字类型的专门问题。
Danubian Sailor'Apr

6

Back2dos已经说了一切,我将尝试进一步阐明我认为最重要的一点:

基数排序只能基于二进制数模式对数组中包含的实际原始值进行排序。在实际的实际软件工程场景中,几乎从未遇到这种情况。我们倾向于做的更多的是对更复杂(非原始)数据结构的排序数组,有时我们对其他实体的索引数组进行排序。

现在,指向其他实体的索引数组实际上是原始数组,但是排序顺序由比较器接口(和/或C#中的委托)提供,该接口不比较索引,而是比较由索引索引的实体。因此,排序顺序与基元值的顺序绝对没有关系,因此,对于这种情况,基数排序绝对没有用。

一个例子:

我们有一个字符串数组:[0] =“ Mike”,[1] =“ Albert”,[2] =“ Zoro”。然后,我们声明这些字符串的索引数组:[0] = 0,[1] = 1,[2] = 2。然后,我们对索引数组进行排序,并向其传递一个比较器,该比较器不比较索引本身,而是比较这些索引引用的实际字符串。排序后,所得的索引数组将如下所示:[0] = 1,[1] = 0,[2] = 2。如您所见,此排序顺序与数组中包含的值的二进制模式无关,但是通过遍历此索引数组并获取每个对应的字符串,我们将按排序顺序访问这些字符串。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.