基数排序浮点数

Posted

技术标签:

【中文标题】基数排序浮点数【英文标题】:Radix Sort Float 【发布时间】:2020-11-09 04:09:24 【问题描述】:

我正在尝试使用基数对浮点数进行排序。我当前的算法适用于无符号。例如,如果我输入值 12、100、1,我的排序值是 1、12 和 100。但是,当我在调用基数排序后使用函数将浮点数转换为整数时,我的值仍然未排序。它们按照用户输入的方式打印。

我不确定如何修改我当前的函数以便能够使用基数对浮点数进行排序。

void rs(unsigned int *a, int c) 
    int i;
    int m = a[0];
    int bt = 0;
    unsigned int *b = malloc(0 * sizeof(int));

    for (i = 0; i < c; i++) 
        if (a[i] > m)
            m = a[i]; 
    

    while((m>>bt) > 0) 
        int buck[2] =  0 ;

        for (i = 0; i < c; i++)  
            buck[(a[i]>>bt)&1]++;
        

        for (i = 1; i < 2; i++)  
            buck[i] += buck[i-1];
        

        for (i = c-1; i >= 0; i--)  
            b[--buck[(a[i]>>bt)&1]] = a[i]; 
        

        for (i = 0; i < c; i++) 
            a[i] = b[i]; 
        
        bt++;
    
    free(b); 

我用来将浮点数转换为整数到浮点数的函数是:Radix Sort for Floats

void rfloat(float* arr, size_t size) 
    assert(sizeof(unsigned) == sizeof(float) && sizeof(float) == 4);
    unsigned* d = malloc(size * sizeof(unsigned));
    
    for (size_t i = 0; i < size; i++) 
        // Interpret float as 32-bit unsigned.
        d[i] = *(unsigned*) &(arr[i]);

        // Flip all except top if top bit is set.
        d[i] ^= (((unsigned) (((int) d[i]) >> 31)) >> 1);

        // Flip top bit.
        d[i] ^= (1u << 31);
    
    
    rs(d, size);
    
    // Inverse transform.
    for (size_t i = 0; i < size; i++) 
        d[i] ^= (1u << 31);
        d[i] ^= (((unsigned) (((int) d[i]) >> 31)) >> 1);
        arr[i] = *(float*) &(d[i]);
    
    
    free(d);

【问题讨论】:

为什么你分配零字节的内存却像分配一些内存一样使用它?那不行 【参考方案1】:

有多个问题。

    您在应该使用unsigned(用于值)或size_t(用于大小/索引)的地方使用int

    你分配了 0 个字节。

    (m &gt;&gt; bt) &gt; 0 不能作为停止条件,未指定移位等于或大于宽度的位。

    将数据类型转换为unsigned 后,循环边界不再起作用。

我冒昧地修复了上述问题并选择了一些更好的变量名:

#include <limits.h>

void rs(unsigned int *a, size_t c) 
    size_t i;
    unsigned bit = 0;
    unsigned *b = malloc(c * sizeof(unsigned));

    unsigned m = a[0]; // Max element.
    for (i = 0; i < c; i++) 
        if (a[i] > m) m = a[i]; 
    

    while (bit < CHAR_BIT*sizeof(m) && (m >> bit))  
        size_t bucket_len[2] =  0, 0 ;
        for (i = 0; i < c; i++) bucket_len[(a[i] >> bit) & 1]++;

        size_t bucket_end[2] = bucket_len[0], bucket_len[0] + bucket_len[1];
        for (i = c; i-- > 0; ) 
            size_t j = --bucket_end[(a[i] >> bit) & 1];
            b[j] = a[i]; 
        

        for (i = 0; i < c; i++) a[i] = b[i]; 
        bit++;
    
    
    free(b); 

【讨论】:

可以避免尝试匹配类型和代码b = malloc(sizeof *b * c);

以上是关于基数排序浮点数的主要内容,如果未能解决你的问题,请参考以下文章

用于浮点数的快速、基于等级的基数排序?

浮点数在c中的基数排序

如何使用分布排序(基数排序等)对字符串进行排序?

10基数排序

排序算法 (11.基数排序)

排序算法之基数排序