首页 > 解决方案 > 通过结构和函数进行数组排序

问题描述

这是我目前正在处理的函数,它与 qsort 函数非常相似。如果数组已排序,则此函数返回 true,否则返回 false。我正在努力解决的问题是弄清楚如何通过数组并调用作为参数给出的比较函数。
我的主要目标是比较数组的每个相邻值,如果 > 0,则返回 false。(注意:这是因为我的比较函数类似于 qsort 函数,如果第一个值更大则返回 1,如果小于则 -1,如果相同则返回 0)。

1.) 如果参数为空,我将如何调用比较函数?另外,我如何每次调用数组“stu”并比较每个部分(ID、名字、姓氏)?我需要 3 个 if 语句吗?

bool areStudentsSorted(Student * stu, int numelem, int (*compar)(const void *, const void *)) {
  for (int i = 0; i <= numelem; i++){

    if (compar(i,i+1) > 0){             <- incorrect 
      //stuck

  return true;
}

这里有两种调用函数的方法

if (!areStudentsSorted(stu, numelem, compareFirstName)) {
          return EXIT_FAILURE;
      }
if (!areStudentsSorted(stu, numelem, compareLastName)) {
          return EXIT_FAILURE;

这是一个比较函数的例子

int compareLastName(const void * p1, const void * p2)
{
    const Student *stu1, *stu2;
    stu1 = p1;
    stu2 = p2;
    return strcmp(stu1->lastname, stu2->lastname);
}

最后,这是结构体 Student

typedef struct
{
  int ID;
  char firstname[NAME_LENGTH] ;
  char lastname[NAME_LENGTH] ;
} Student;

标签: arrayscsortingstructqsort

解决方案


如果参数为空,我将如何调用比较函数?

参数不是void,它们是void *。当您为参数传递一个指针时void *,您可以传递任何类型的指针。它将被隐式转换为void *参数。

但是,您的函数调用不正确:

compar(i,i+1)

变量i不是指针,它是表示数组索引的整数。相反,您应该传递一个指向Student结构的指针。所以你应该写

compar( &stu[i], &stu[i+1] )

反而。该&运算符是“地址”运算符。

另外,你应该改变

for (int i = 0; i <= numelem; i++){

for (int i = 0; i < numelem - 1; i++){

否则您将越界访问数组。


另外,我如何每次调用数组“stu”并比较每个部分(ID、名字、姓氏)?我需要 3 个 if 语句吗?

如果您希望比较函数在确定排序顺序时考虑所有 3 个字段,那么您必须决定应根据哪些标准对学生进行排序。例如,您可能希望学生主要按姓氏排序,如果多个学生的姓氏相同,则应按名字排序,如果多个学生的姓氏和名字相同,您可能希望他们将根据他们的ID进行排序。在这种情况下,您可以编写一个相应的比较函数,该函数将所有 3 个标准都考虑在内:

int compareByAllThreeCriteria( const void * p1, const void * p2 )
{
    int ret;

    //compare last name
    ret = compareLastName( p1, p2 );
    if ( ret != 0 )
        return ret;

    //last name is identical, so it should be sorted by first name
    ret = compareFirstName( p1, p2 );
    if ( ret != 0 )
        return ret;

    //both names are identical, so it should be sorted by ID
    return compareID( p1, p2 );
}

您还可以将函数compareLastName,compareFirstName和组合compareID成一个大的比较函数:

int compareByAllThreeCriteria( const void * p1, const void * p2 )
{
    const Student *stu1, *stu2;
    stu1 = p1;
    stu2 = p2;

    int ret;

    //first compare the last name
    ret = strcmp(stu1->lastname, stu2->lastname);
    if ( ret != 0 )
        return ret;

    //last name is identical, so it should be sorted by first name
    ret = strcmp( stu1->firstname, stu2->firstname );
    if ( ret != 0 )
        return ret;

    //both names are identical, so it should be sorted by ID
    if ( stu1->ID < stu2->ID )
        return -1;
    if ( stu1->ID > stu2->ID )
        return +1;

    //if they are not smaller or greater, they must be equal
    return 0;
}

推荐阅读