【问题标题】:A fast, rank based Radix Sort for floats?用于浮点数的快速、基于等级的基数排序?
【发布时间】:2013-08-30 22:58:58
【问题描述】:

我正在寻找一种快速稳定的基数排序实现(支持浮点数),它返回排序顺序的索引而不是排序值。

Pierre Terdiman 的文章"Radix Sort Revisited" 中的版本完全符合我的要求,但是它已经超过 13 年了,不适合现代流水线 CPU。

Michael Herf 的来自"Radix Tricks" 的 RadixSort11 非常快,唯一的问题是它返回排序后的值而不是索引,此外它还会破坏输入数组的值。

任何帮助将不胜感激。

【问题讨论】:

    标签: c++ algorithm sorting radix-sort


    【解决方案1】:

    你可以

    1. 扩展每个项目以包括其原始索引(这可以在第一次计数过程中完成)。当然,出于排序目的,索引数字会被忽略。

    2. 将索引而不是值存储到存储桶中。每次需要数字时查找值。

    第一个占用更多空间但具有更好的参考局部性,第二个节省空间。

    【讨论】:

      【解决方案2】:

      基于任何排序索引是相当直接的。 任何排序都是一系列的比较和交换,所以这样做。

      // data to be sorted is in data[ 0 .. n ]
      int index[ n + 1 ];
      for( int i = 0; i <= n; i++ ) index[i] = i;
      // To compare data, compare data[index[j]] < data[index[k]]
      // To swap values, swap index[j] <=> index[k]
      

      【讨论】:

      • 基数排序不是基于比较的排序方法,这就是为什么它比大多数基于比较的方法执行得更好。
      • 嗯。我相当确定 OP 对如何 比较排序 有一个绰绰有余的想法。这不是这个问题的主题。
      • @plasma:尽管如此,显示的技术(插入间接)应该同样适用于基数排序。您将测试来自data[index] 的数字,然后将index 插入到相应的存储桶中。
      【解决方案3】:

      我不熟悉这些实现,但这是我的一个实现中的内部函数,仅适用于整数:

      //-------------------------------------------------------------------------------------
      //! sort the source array based on b-th byte and store the result in destination array
      //! and keep index (how to go from the sorted array to the un-sorted)
      
      template<typename T, typename SS, typename SD> inline
      void radix_sort_byte(size_t b, array<T, SS>& src, array<T, SD>& dest,
                   size_array& ind_src, size_array& ind_dest)
      {
          b *= 8;
          size_t B = 256, N = src.size();
      
          size_array bytes = (src >> b) & 0xff;  // current byte of each element
          size_array count(B, size_t(0));  // occurrences of each element
          ++count[bytes];
      
          if(count[0] == N)  // all bytes are zero; order remains unchanged
              { dest = src; ind_dest = ind_src; return; }
      
          size_array index = shift(cumsum(count), 1);  // index-list for each element
          size_array pos(N);  // position of each element in the destination array
          for(size_t i=0; i<N; i++) pos[i] = index[bytes[i]]++;
      
          dest[pos] = src;  // place elements in the destination array
          ind_dest[pos] = ind_src;  // place indices
      }
      

      它不是直接可读的,因为它使用了许多辅助结构和函数,但其​​想法是您保留一个带有索引的单独数组。获得目标数组 (pos) 中元素的位置后,最后两行以完全相同的方式更新值数组和索引数组。

      我想您可以将相同的想法应用于任何实现,但您必须修改代码。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-07
        • 2013-12-08
        • 1970-01-01
        • 1970-01-01
        • 2015-05-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多