我发现java.util.Arrays.sort(Object[])
使用了两种排序算法(在JDK 1.6中)。
伪代码:
if(array.length<7)
insertionSort(array);
else
mergeSort(array);
为什么这里需要2种排序?效率?
答案 0 :(得分:45)
值得注意的是,O(N log N)
算法在实践中并不总是比O(N^2)
算法快。它取决于常数和N
所涉及的范围。 (请记住asymptotic notation衡量的是相对增长率,而不是绝对速度。
对于小N
,插入排序实际上确实击败了合并排序。几乎排序的数组也更快。
这是a quote:
虽然它是具有
O(N^2)
最坏情况时间的基本排序算法之一,但是当数据几乎排序(因为它是自适应的)或问题大小很小时,插入排序是选择的算法(因为它的开销很低)。由于这些原因,并且因为它也是稳定的,插入排序通常用作递归基本情况(当问题大小很小时),用于更高开销的分而治之的排序算法,例如合并排序或快速排序
以下是Best sorting algorithm for nearly sorted lists论文的另一个引用:
直接插入排序最适合小型或非常接近排序的列表
这意味着,在实践中:
N
的范围内无关紧要
让我们考虑这两个功能:
f(x) = 2x^2
;该函数具有二次增长率,即“O(N^2)
”g(x) = 10x
;此函数具有线性增长率,即“O(N)
”现在让我们将两个函数绘制在一起:
来源: WolframAlpha: plot 2x^2 and 10x for x from 0 to 10
请注意,在x=0..5
,f(x) <= g(x)
之间,但对于任何较大的x
,f(x)
很快就会超过g(x)
。
类似地,如果 A 1 是具有低开销的二次算法,并且 A 2 是高开销的线性算法,对于较小的输入, A 1 可能比 A 2 更快。
因此,如果您选择这样做,您可以创建一个混合算法 A 3 ,它根据输入的大小选择两种算法中的一种。 。这是否值得付出努力取决于所涉及的实际参数。
已经对排序算法进行了许多测试和比较,并且决定因为插入排序对小型数组进行合并排序,因此为Arrays.sort
实现两者都是值得的。
答案 1 :(得分:5)
这是为了速度。 mergeSort的开销足够高,对于短数组,它会比插入排序慢。
答案 2 :(得分:3)
引自:http://en.wikipedia.org/wiki/Insertion_sort
Some divide-and-conquer algorithms such as quicksort and mergesort sort by
recursively dividing the list into smaller sublists which are then sorted.
A useful optimization in practice for these algorithms is to use insertion
sort for sorting small sublists, where insertion sort outperforms these more
complex algorithms. The size of list for which insertion sort has the advantage
varies by environment and implementation, but is typically between eight and
twenty elements.
答案 3 :(得分:1)
看起来他们认为mergeSort(array
)对于短阵列来说速度较慢。希望他们真的测试过。