【问题标题】:Using radix sort/counting sort for array of structs in C?对C中的结构数组使用基数排序/计数排序?
【发布时间】:2015-07-19 19:49:24
【问题描述】:

我有一个包含 uint32_t 类型的结构数组。知道数组的最大值和最小值后,我想实现计数排序或基数排序以根据 uint32_t 对数组进行排序。值的范围可能非常大。我不知道如何对结构数组而不是整数进行排序。或者有没有更好的算法来进行这种排序?谢谢!

【问题讨论】:

  • 首先:使用包含 int 的结构实现更简单的排序,例如冒泡排序。一旦你弄清楚如何做到这一点,你就可以继续进行基数排序。不要试图一步完成所有事情。
  • 如果您的结构中包含除 uint32_t 之外的其他成员,您希望将其用作排序键,那么标准计数排序是不可能的,因为它依赖于具有相同值的整数的不可区分性.如您所说,如果值的范围很大,那么无论如何计数排序可能都是一个坏主意,因为它在时间和内存中按 O(R+N) 缩放,其中 R 是 range正在排序的值。

标签: c arrays struct radix-sort counting-sort


【解决方案1】:

一次对 32 位整数的一个字节进行计数基数排序(请注意,这必须首先执行最低有效字节,最后才是最高有效字节)。对数组进行排序需要 4 次排序。对于基数排序的每次传递,您都需要第二个数组来移入/移出。

通过使用 4(每个 32 位整数有 4 个字节)x 256(每个字节有 256 个可能值)的索引矩阵(最初这些是计数,但转换为索引),填充在矩阵中只通过一次数组。

因此,使用基于 32 位整数值的 4 个字节的计数/基数排序,结构数组总共有 5 次读取传递和 4 次写入传递。

【讨论】:

    【解决方案2】:

    如果使用qsort,需要提供比较功能,像这样

    struct Foo
    { 
       uint32_t index;
       other stuff;
    }
    
    
    int compareMyType (const void * a_, const void * b_)
    {
      const Foo* a = a_;
      const Foo* b = b_;
    
      if ( a->index <  b->index ) return -1;
      if ( a->index == b->index ) return 0;
      if ( a->index >  b->index ) return 1;
    }
    
    Foo foos[100];
    qsort(foos,100,compareMyType );
    

    对于整数,基数排序可能更快,但如果您真的关心效率,您不会对结构数组进行排序,而是对结构指针数组进行排序,因为在复制数据时会产生大量开销。

    【讨论】:

    • 感谢您的回答!我确实实现了带有比较功能的 qsort。但是如何实现基数排序来对指针数组进行排序呢?
    • 在基数排序中,您创建 N 个 bin,然后循环遍历数组并将每个元素放入其中一个 bin(基于您要排序的数字),然后将这些 bin 重新合并在一起。对每个数字重复此操作,直到完成。在您的情况下,不是将 integer 放入 bin 中,而是将 pointer 放入 bin 中。
    猜你喜欢
    • 2015-08-31
    • 1970-01-01
    • 1970-01-01
    • 2019-07-14
    • 1970-01-01
    • 1970-01-01
    • 2020-07-17
    • 2021-07-16
    • 2018-07-02
    相关资源
    最近更新 更多