如何在C中按给定成员对结构数组进行排序

时间:2016-11-22 21:48:40

标签: c arrays sorting struct

我有这样的结构:

struct Car {
    int weight;
    int price;
    int speed;
    etc..}

我想编写一个函数来对这种结构的数组进行排序。

void sortCars(struct Car table[], int tableSize, ?structMemberParameter?)
{
    struct Car temp;
    int swapped;
    for (int i = 0; i < tableSize; i++)
    {
        swapped = 0;
        for (int j = 0; j < tableSize - 1; j++) {
            if (table[j].?structMemberParameter? > table[j + 1].?structMemberParameter?) {
                temp = table[j + 1];
                table[j + 1] = table[j];
                table[j] = temp;
                swapped = 1;
            }           
        }
        if (swapped == 0) {
            break;
        }
    }
}

我应该把它作为“?structMemberParameter?”?

1 个答案:

答案 0 :(得分:2)

编写一个比较函数,比较两个结构中的成员并使用qsort()。您可以在qsort(3)手册中看到该示例。

这是问题标题的答案,您问题的答案是您不需要传递成员,但比较函数就像qsort()那样。

因此if语句变为

if (compare(&table[j], &table[j + 1]) > 0) ...

和函数签名

typedef int (*cmpfn_type)(const struct Car *const, const struct Car *const);
void sortCars(struct Car table[], int tableSize, cmpfn_type compare);

所以你可以有多个比较功能,例如,假设你想按价格进行比较,那么适当的就是

int compare_by_price(const struct Car *const A, const struct Car *const B)
{
    return (int) (A->price - B->price);
}

你应该注意类型转换。

这种方法的好处在于,您可以轻松地重写比较函数以使用qsort()库函数。

注意:在评论中回答您的评论/问题,您也可以有一个枚举器,例如

enum CarProperties {
    Speed, Price // ... AND SO ON
};

然后是一个类似

的排序函数
void sort_car_array(struct Car *const array,
        size_t size, enum CarProperties sort_property);

你有一个switch语句,可以选择适当的回调来传递给像generic_car_array_sort()之类的通用排序,就像上面建议的那样,甚至可以直接传递给qsort()更好的解决方案。

如果您打算使用struct Car结构的API,您可以这样做,我认为这是一个非常优雅的解决方案。我还建议使结构不透明,并允许调用者仅通过函数设置/获取值。