是否有一个稳定的排序算法.Net比O(n log n)快两倍?

时间:2012-04-25 18:56:11

标签: .net algorithm sorting double

我需要一个稳定的排序算法,用于.Net双打,比O(n log n)快。

我正在考虑Radix排序。但是,如果我理解正确,它的性能是O(n k),因为我正在排序双打,k = 8.如果n> 1,这将使它仅比O(n log n)排序(即QuickSort)更快。 2980.(这是正确的吗?)在我的情况下,n通常更接近500或1000但有时也更大。 (是的,这种排序经常发生非常,并且基于分析分析,它的速度确实很重要。)

我应该坚持使用QuickSort还是有其他更快的选择?斗式排序怎么样?我正在寻找C#或VB.NET中的良好实现。

编辑:我目前正在使用稳定的QuickSort实现。

编辑:请参阅Radix的此实现以获取浮点值:http://codercorner.com/RadixSortRevisited.htm。根据这个,对于双打,k将是9。

2 个答案:

答案 0 :(得分:2)

实际上doulbes的基数排序将具有复杂度n * k,其中k为64而不是8(经典基数排序使用数字的二进制表示)。任何输入都不会更快。如前所述,对于少量输入值,快速排序将更快,并且还注意到C ++中std :: sort的一些实现使用O(n ^ 2)算法来完成少量值的排序(实际上小数字),通常是插入排序(看看here)。因此,几种算法之间的混合可能最适合您。

答案 1 :(得分:1)

基数排序是O(n * k),其中k往往是log(n) - 因为k是数字位数,并且位数随着最大数字的大小的对数而变化。

另外,查看float或double的二进制表示不太可能产生可以排序的东西。您可以将其转换为小数点后面带有一定数字位数的十进制字符串,如果您避免使用科学记数法,则可以进行基数排序。

你可能最好使用.Net排序方法(它可能已被优化了很多),或者是一个timsort。

在渐近分析中,您正在查看曲线的形状,而不是其在轴附近的图形上的绝对位置。这是因为,对于足够大的n,形状比穿过轴的位置更重要。

因此,如果您没有对大型列表进行排序,那么最好使用快速排序或甚至插入排序等更好的排序。

在紧密循环中进行排序很少是一个好主意 - 这样的设计通常更好地替换为使用堆,treap,红黑树,跳过列表,splay树或其他log(n)数据结构的东西。

我不认为quicksort是稳定的,虽然它可以在一点性能上受到惩罚。

mergesort很容易编码,与timsort有关,而且稳定。蒂姆索特也很稳定。

这是一张支持细节的图表:

linear-linear graph of a few sorts