一个快速,基于排名的Radix Sort for floats?

时间:2013-08-30 22:58:59

标签: c++ algorithm sorting radix-sort

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

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

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

任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:2)

你可以

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

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

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

答案 1 :(得分:1)

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

// 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]

答案 2 :(得分:0)

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

//-------------------------------------------------------------------------------------
//! 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)中有元素的位置,最后两行就会以完全相同的方式更新值数组和索引数组。

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