针对特定情况的最快排序算法

时间:2010-06-08 14:11:04

标签: algorithm language-agnostic sorting performance

对于大量(数万)9个正双精度值组的最快排序算法是什么,其中每个组必须单独排序?因此,它必须连续多次快速排序少量可能重复的双精度值。 值在[0..1]间隔内。我不关心空间复杂性或稳定性,只关心速度。

4 个答案:

答案 0 :(得分:8)

单独对每个组进行排序,合并排序可能最容易实现并获得良好的结果。

分拣网络可能是最快的解决方案: http://en.wikipedia.org/wiki/Sorting_network

答案 1 :(得分:1)

很好的问题,因为这归结为“对9个元素进行排序的最快方式”,并且排序方法之间的大多数比较和分析都是大N.我假设'组'是明确定义的并且不玩这里真正的角色。

你可能需要对一些候选人进行基准测试,因为很多因素(地点)在这里发挥作用。

无论如何,让它平行听起来是个好主意。如果可以使用NET4,请使用Parallel.For()

答案 2 :(得分:1)

我认为你需要尝试一些例子来看看哪种方法效果最好,因为你有一套不寻常的条件。我猜最好的将是

之一
  • 排序网络
  • 插入排序
  • 快速排序(一级 - 下面的插入排序)
  • 合并排序

鉴于双精度数相对较长,我怀疑你使用基数排序不会做得更好,但可以随意添加。

为了它的价值,Java对双打使用快速排序,直到要排序的项目数量低于7,其中使用插入排序。第三种选择模仿该解决方案。

此外,您的整体问题是embarrassingly parallel,因此您希望尽可能使用并行性。对于分布式解决方案来说,问题看起来太小(在网络中丢失的时间比保存的要多),但如果设置正确,您的问题可以非常有效地利用多个核心。

答案 3 :(得分:1)

看起来你想要最循环的吝啬方式来排序9个值。由于值的数量有限,我会(如Kathy所建议的)首先对前4个元素和后5个元素进行展开插入排序。然后我会合并这两组。

这是一个展开的插入类型的4个元素:

if (u[1] < u[0]) swap(u[0], u[1]);
if (u[2] < u[0]) swap(u[0], u[2]);
if (u[3] < u[0]) swap(u[0], u[3]);

if (u[2] < u[1]) swap(u[1], u[2]);
if (u[3] < u[1]) swap(u[1], u[3]);

if (u[3] < u[2]) swap(u[2], u[3]);

这是一个合并循环。第一组4个元素位于u中,第二组5个元素位于v中。结果在r

i = j = k = 0;
while(i < 4 && j < 5){
  if (u[i] < v[j]) r[k++] = u[i++];
  else if (v[j] < u[i]) r[k++] = v[j++];
  else {
    r[k++] = u[i++];
    r[k++] = v[j++];
  }
}
while (i < 4) r[k++] = u[i++];
while (j < 5) r[k++] = v[j++];