【问题标题】:Sorting an array of pointers to struct based on an element inside the struct根据结构内的元素对指向结构的指针数组进行排序
【发布时间】:2018-04-24 10:08:24
【问题描述】:

我在这里要做的是根据 Struct 中的字符串对指向 Structs 的指针数组进行排序。我认为只交换数组中的指针而不是交换整个 struct 会很容易。所有元素都是动态分配的。我的代码是用德语写的,所以我只会用英语写我看不懂的部分。提前感谢您的帮助。

typedef struct Vehicle {
    char *manufacturer;
    char *serialnumber;
    int weight;
};
void SortByID(struct fahrzeug** data, int Anzahl){ 
    struct Vehicle *temp= (struct Vehicle*)malloc( sizeof(struct Vehicle) );
    int i =0 ;// I think i've written something wrong here ( strcmp)
    while ( i < Anzahl && strcmp(data[i]->serialnumber, data[i+1]->serialnumber) < 0) 
    {
         temp = data[i+1];
         data[i+1] = data[i];
         data[i]=temp ;
         i++;
    }  
    free(temp);
    temp=NULL;
}
int main(){
    int count =0 ;
    struct Vehicle **array = NULL ;
    array=(struct Vehicle**)malloc(  5 * sizeof(struct Vehicle*)  );
    for(int i=0;i<5 ;i++){
       array[i] = (struct Vehicle*)malloc( sizeof(struct Vehicle) ) ;
       count++;
    }
    SortByID (  &array, count ) ; // is this right ?
    return 0; 
}

我也尝试使用 qsort 函数对其进行排序,但没有成功

int compare(const void *a, const void *b) {
  struct Vehicle * const *one = a;
  struct Vehicle * const *two = b;

  return strcmp((*one)->serialnumber, (*two)->serialnumber);
}
void SortByID(struct Vehicle** data, int Anzahl){
   qsort( data, Anzahl, sizeof(struct Vehicle*) ,compare );
}

【问题讨论】:

  • 您可以使用qsort() 而不是编写自己的排序函数。
  • 谢谢,我会试试的。qsort 只会交换数组内的指针位置?
  • qsort() 将交换数组中的数据,无论它是什么类型和大小。在您的情况下,数据是一个指针,因此将按照比较函数的指示进行交换。
  • 这样可以吗:int compare ( struct Vehicle*a, struct Vehicle* b){ return strcmp(a-&gt;serialnumber, b-&gt;serialnumber); } void SortByID(struct fahrzeug** data, int Anzahl){ qsort( data, Anzahl, sizeof(struct fahrzeug*) ,compare ); }
  • 看起来不错。试试看。

标签: c arrays sorting pointers struct


【解决方案1】:

这是一个使用qsort() 的工作示例。它可以按序列号和制造商排序。

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

struct Vehicle {
    char *manufacturer;
    char *serialnumber;
    int weight;
};

int cmp_serialnumber(const void *p1, const void *p2)
{
    const struct Vehicle *v1 = *(struct Vehicle * const *)p1;
    const struct Vehicle *v2 = *(struct Vehicle * const *)p2;

    return strcmp(v1->serialnumber, v2->serialnumber);

/*
    // Alternatively You could write this function as this less readable one liner
    return strcmp((*(struct Vehicle * const *)p1)->serialnumber,
                    (*(struct Vehicle * const *)p2)->serialnumber);
*/
}

int cmp_manufacturer(const void *p1, const void *p2)
{
    const struct Vehicle *v1 = *(struct Vehicle * const *)p1;
    const struct Vehicle *v2 = *(struct Vehicle * const *)p2;

    return strcmp(v1->manufacturer, v2->manufacturer);
}

void print_vehicles(struct Vehicle **vehicles, int n) {
    for (int i=0; i<n; i++) {
        printf("%s, %s, %d\n", vehicles[i]->serialnumber,
                vehicles[i]->manufacturer, vehicles[i]->weight);
    }
}


#define N_VEHICLES  5
char *manufacturers[] = {"McLaren", "Ferrari", "Renault", "Mercedes", "Alfa Romeo"};
char *serialnumbers[] = {"SN500", "SN4", "SN8", "SN2", "SN1"};


int main(){
    struct Vehicle **vehicles = NULL;

    vehicles = (struct Vehicle**)malloc(N_VEHICLES * sizeof(struct Vehicle *));

    for(int i=0; i<N_VEHICLES; i++) {
        vehicles[i] = (struct Vehicle *)malloc(sizeof(struct Vehicle));
        vehicles[i]->manufacturer = manufacturers[i];
        vehicles[i]->serialnumber = serialnumbers[i];
        vehicles[i]->weight = 1000;
    }

    printf("Before\n");
    print_vehicles(vehicles, N_VEHICLES);
    printf("\n");

    // sort by serial number
    qsort(vehicles, N_VEHICLES, sizeof(struct Vehicle *), cmp_serialnumber);
    printf("Sorted by serial number\n");
    print_vehicles(vehicles, N_VEHICLES);
    printf("\n");

    // sort by manufacturer
    qsort(vehicles, N_VEHICLES, sizeof(struct Vehicle *), cmp_manufacturer);
    printf("Sorted by manufacturer\n");
    print_vehicles(vehicles, N_VEHICLES);

    return 0;
}

【讨论】:

  • 谢谢。你帮了我很多。
  • 将 qsort 与指针对指针查找表一起使用并不是一个好主意。它只会浅拷贝指针,而不是实际数据。因此,如果在调用 qsort 之前您有一个指向某个 Vehicle 的指针,那么该指针现在将指向错误的位置。最好使用实际的二维数组。
  • @Lundin:也许你的观点对我来说太微妙了,但我无法引发问题。我的理解是struct Vehicle **vehicles 中的值,即指向车辆的指针,将在不修改且不修改任何引用数据的情况下进行洗牌。如果你持有一个 pointer to a pointer 到车辆,那么你可以看到变化,但这不是这里发生的事情(我认为),也不是你所描述的(你只提到了一个“指针到某个车辆”)。您能否添加一个答案,说明在这种情况下如何正确使用qsort()
猜你喜欢
  • 2021-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-02
  • 2016-01-08
  • 2020-03-15
  • 2017-01-04
相关资源
最近更新 更多