【问题标题】:Sorting structure of arrays with qsort使用 qsort 对数组进行排序结构
【发布时间】:2012-07-27 15:23:42
【问题描述】:

通常对结构对象数组进行排序很容易。考虑结构数组(AOS)

#define ITEMS 10

typedef struct MyStruct
{
 char a;
 int  b;
}tMyStruct;

tMyStruct arr_mystruct[ITEMS];

我首先用 对的值填充这个结构数组。

如果我现在想根据整数字段对这个结构数组进行排序,我可以使用 libc qsort 函数通过使用一个接受两个整数参数的比较函数来完成。

现在考虑我把上面AOS格式的结构换成SOA格式

#define ITEMS 10

typedef struct MyStruct
{
 char a[ITEMS];
 int  b[ITEMS];
}tMyStruct;

tMyStruct mystruct;

现在我仍然可以使用 qsort 对整数数组 b 字段进行排序,但是这次我需要另外对 a(字符数组)w.r.t b 的排序顺序进行排序。

所以我的问题是,对以 SOA 格式而不是通常的 AOS 格式布局的数据进行排序的有效方法是什么?

谁能帮我解决这个问题?谢谢!

【问题讨论】:

  • a w.r.t sorting order of b。你能帮我翻译一下吗...
  • @AljoshaBre 表示'a 相对于 b 的排序顺序'
  • 我认为他想对数组ab 进行排序,以便它们都根据b 的数据进行排序。换句话说,将所有数据对放在一起。
  • 您已使用 C++ 标记此内容,您对 C++ 解决方案感兴趣吗?那些不能在 C 中工作的?
  • 如果std::sort 只能通过std::lessstd::swap 起作用,那么您可以通过提供一个自定义std::swap 来解决您的问题,该std::swap 也可以处理as。否则真的没有“好的”解决方案。

标签: c sorting structure


【解决方案1】:

可能最好的方法是使用辅助数组:

int helper[ITEMS];

int helper_cmp(const void *a, const void *b);

for (i = 0; i < ITEMS; ++i)
    helper[i] = i;
qsort(helper, ITEMS, sizeof(*helper), helper_cmp);

helper_cmp 函数将helper 值作为mystruct.b 的索引并比较这些值:

int helper_cmp(const void *a, const void *b)
{
    int first = *(const int *)a;
    int second = *(const int *)b;
    int b_first = mystruct.b[first];
    int b_second = mystruct.b[second];
    // compare b_first and b_second
}

然后,在qsort 之后,辅助数组将包含重新排列的b 索引,告诉它应该如何排序。

您可以使用此数组重新排列mystruct.amystruct.b


请注意,这不如排序“结构数组”有效。我不知道您的应用程序,但我的猜测是“数组结构”,其中数组的字段是相关的,首先不是一个好主意。也就是说,如果b 的排序影响a 的排序,它们可能属于同一个概念元素(如果你愿意,可以称之为类),最好将它们组合在一个struct 中。

【讨论】:

  • SOA 方法在多核(SIMDization、缓存效率)和 GPU(CUDA) 中经常使用。
【解决方案2】:

除了辅助建议之外,没有其他方法可以使用 qsort() 执行此操作。对于这样的情况,我会编写自己的排序函数。为了在速度和易于编写之间取得最佳平衡,我发现插入排序适用于小型数组,而合并排序适用于大型数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-07
    • 2014-07-04
    • 2021-05-08
    • 2014-05-21
    • 2021-07-16
    相关资源
    最近更新 更多