代码之家  ›  专栏  ›  技术社区  ›  Mithaldu

0-65535整数的最快排序算法是什么?

  •  8
  • Mithaldu  · 技术社区  · 17 年前

    我必须对一些整数进行排序,它们的值可以在30.000.000和350.000.000之间。将有0到65.535个整数,平均计数为20.000。RAM的使用是不相关的,速度才是重要的。

    稍后,我还将不得不将它们分成若干组,每当其中两个值之间的差距为>65.535,这就是我需要算法的原因。

    如果有任何不同,该算法将在Perl脚本中使用。

    Edit2:经过一些测试和尝试提供的答案,我发现最快的方法是:

    my @sort = sort {$a <=> $b} @item_offsets;
    my @buckets;
    my $start = shift @sort;
    push @buckets, [$start,$start];
    for my $item ( @sort ) {
        if ( $item < $buckets[$#buckets][1]+$gap ) {
            $buckets[$#buckets][1] = $item;
        }
        else {
            push @buckets, [$item,$item];
        }
    }
    say $#buckets;
    
    6 回复  |  直到 17 年前
        1
  •  17
  •   Brian    17 年前

    在运行算法之前,我只需要创建一个桶数组,每组65536个连续值对应一个桶。存储桶将包含其内容的最小值和最大值,但不会存储内容本身。运行该算法后,对桶进行一次遍历。如果有两个连续的非空铲斗,最小(bucket2)-最大(bucket1)<65536,把它们合起来。在算法完成运行之前,不会进行合并。丢弃所有空桶。该算法是线性时间的。

    注意到 Bucket Sort .

        2
  •  17
  •   Michael Carman    17 年前

    您不太可能用Perl编写一个比Perl的内置算法性能更好的排序算法 sort 功能:

    @numbers = sort {$a <=> $b} @numbers;
    

    您可以使用sort pragma进行实验,以查看特定算法是否更好:

    use sort '_quicksort';
    use sort '_mergesort';
    

    由于切割点会因数据分布的不同而有所不同,因此我认为您需要先对整个列表进行排序,然后在其上循环进行切割。

    my $prev  = shift @numbers;  # already sorted
    my @group = [$prev];
    my $i     = 0;
    
    foreach my $n (@numbers) {
        $i++ if ($n - $prev > 65535);
        push @{$group[$i]}, $n;
        $prev = $n;
    }
    
        3
  •  12
  •   FlySwat    17 年前

    我会使用基数排序,因为需要对输出进行分组。

        4
  •  5
  •   Chris Marisic    17 年前

    我只是想说基数排序, http://en.wikipedia.org/wiki/Radix_sort 然而,这可能比您希望实现的要高一点,Introsort通常是公认的数据排序解决方案 http://en.wikipedia.org/wiki/Introsort ,它是quicksort的一种变体,当它到达较小的集合时会切换到heapsort,因为它在较小集合上比quicksort更快。

        5
  •  1
  •   Leon Timmermans    17 年前

    my @sorted = map { unpack "N" } sort map { pack "N" } @unsorted;
    
        6
  •  0
  •   warren    17 年前

    在伪代码中:

    while(morenumbers)
      sorted[[unsorted[number]]++
      number++
    

    如果提前知道范围,则可以减少索引值(例如,值-30000以使其进入正确的范围)。