繁体   English   中英

使用 qsort 对 C 中的结构数组进行排序

[英]Sorting array of structs in C using qsort

让我们定义一个名为“Edge”的结构。

#include <stdio.h>
#include <stdlib.h>

struct Edge{
    int first;
    int second;
    float score;
};

struct Edge* newEdge(int first, int second, float score){
    struct Edge* edge = (struct Edge*)malloc(sizeof(struct Edge*));
    edge->first = first;
    edge->second = second;
    edge->score = score;
    return edge;
}

给定一个边数组,每个边由两个顶点和一个分数组成,我必须按分数的降序/升序对边进行排序。 我写了一个比较器 function。 以下是我尝试过的。 但是,它不会产生正确的 output。

int comparator_function(const void *v1, const void *v2){
    struct Edge* e1 = (struct Edge*) v1;
    struct Edge* e2 = (struct Edge*) v2;
    if(e1->score < e2->score){
        return 1;
    }
    return 0;
}

int main(){
    struct Edge* edges[5];
    edges[0] = newEdge(1, 2, 1.23);
    edges[1] = newEdge(4, 3, 3.222);
    edges[2] = newEdge(2, 2, 5.222);
    edges[3] = newEdge(5, 1, 4.222);
    edges[4] = newEdge(3, 4, 2.4);
    for(int i=0;i<5;i++){
        printf("%d, %d, %f\n", edges[i]->first, edges[i]->second, edges[i]->score);
    }
    printf("\n\n");

    qsort(edges, 5, sizeof(struct Edge*), comparator_function);

    for(int i=0;i<5;i++){
        printf("%d, %d, %f\n", edges[i]->first, edges[i]->second, edges[i]->score);
    }
    return 0;
}

我得到的快速排序的 output 是 -

4, 3, 3.222000
5, 1, 4.222000
2, 2, 5.222000
1, 2, 1.230000
3, 4, 2.400000

我不确定我的比较 function 是否正确。 任何帮助,将不胜感激。

首先,分配

    struct Edge* edge = (struct Edge*)malloc(sizeof(struct Edge*));

是错的。 您必须为结构分配,而不是指针。

它应该是

    struct Edge* edge = malloc(sizeof(*edge));

或者

    struct Edge* edge = malloc(sizeof(struct Edge));

(另请注意malloc()的强制转换结果被认为是一种不好的做法

那么,比较 function 是错误的。

  • 当第一个元素“小于”第二个元素时,您必须返回-1
  • arguments 是指向元素的指针(在本例中为struct Edge* )。

它应该是这样的:

int comparator_function(const void *v1, const void *v2){
    /* correct casting type and add dereferencing */
    struct Edge* e1 = *(struct Edge**) v1;
    struct Edge* e2 = *(struct Edge**) v2;
    if(e1->score < e2->score){
        return 1;
    }
    /* add this */
    if(e1->score > e2->score){
        return -1;
    }
    return 0;
}

传递给qsort的比较 function 应该返回:

  • 小于 0,如果左边的值更小
  • 0,如果值相等
  • 大于0,如果左边的值更大

您的比较 function 仅返回值 0 和 1,因此左侧参数无法更大。 您需要添加一个额外的案例来解决这个问题。

另一个问题是,由于您的数组元素类型是struct Edge * ,传递给比较 function 的指针将是struct Edge **类型,因此您需要进行与此相关的更改。

int comparator_function(const void *v1, const void *v2){
    struct Edge * const *e1 = v1;
    struct Edge * const *e2 = v2;
    if((*e1)->score < (*e2)->score){
        return 1;
    } else if((*e1)->score > (*e2)->score){
        return -1;
    } else {
        return 0;
    }
}

此外,您没有分配适量的 memory:

struct Edge* edge = (struct Edge*)malloc(sizeof(struct Edge*));

这只为指针分配空间,而不是整个结构。 你要:

struct Edge* edge = malloc(sizeof(struct Edge));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM