在 C 中使用函数指针的 Bubblesort 算法

Bubblesort algorithm with Function Pointers in C

我需要使用冒泡排序算法按姓名或年龄升序对结构数组进行排序的代码。

我阅读了所有的元素并且我理解了排序的部分。问题是我应该只声明一种能够根据姓名或年龄排序的冒泡排序算法。此外,当两个名字或年龄相同时,我应该比较不相同的元素。为此,我应该使用一个函数指针。我刚刚开始使用函数指针,我在这里看不到出路。如果能提供一点帮助,我们将不胜感激。

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

struct person {
    char name [30];
    int age;
};

void bubblesort(struct person *prs, int n)
{
struct person temp;
int i, j , a,b;


for(i=0;i<n; i++)
{
    for(j=0; j <n-1; j++)
    {
        a=strcmp(prs[j].name, prs[j+1].name);
        b=prs[j+1].age - prs[j].age;

        if(a>0)
        {
            temp=prs[j];
            prs[j]=prs[j+1];
            prs[j+1]=temp;
        }
        else if(a==0 && b<0)
        {
            temp=prs[j];
            prs[j]=prs[j+1];
            prs[j+1]=temp;
        }
    }
}
}

int main()
{

int n, i;
 struct person *prs;

scanf("%d", &n);
getchar();

prs=(struct person *)malloc(sizeof(struct person)*n);

for(i=0;i<n;i++)
{
    fgets(prs[i].name, 30, stdin);
    prs[i].name[strlen(prs[i].name)-1]='[=10=]';
    scanf("%d", &prs[i].age);
    getchar();
}

bubblesort(prs,n);

 for(i=0;i<n;i++)
 {
   printf("{%s, %d};", prs[i].name, prs[i].age);

 }
 return 0;
 }

将此函数原型用于冒泡排序:

void bubblesort(struct person *prs, int n, int (*cmp)(struct person *a, struct person *b)) {...}

现在创建一个比较函数来比较两个人:

int cmpTwoPersons(struct person *a, struct person *b) {...}

这个函数应该return一个大于0的数字如果a>b,小于0如果a

使用这个比较函数调用你的冒泡排序:

bubblesort(prs, n, cmpTwoPersons);

现在您在冒泡排序中使用 cmp

void bubblesort(...) {
    ...
    int cmpResult = cmp(prs[j], prs[j+1]);
    if (cmpResult > 0) {
        // j is large than j+1
    } else {
        // j is smaller than or equal to j+1
    }
    ...
}

您的冒泡排序签名可以是:

void bubblesort(void **prs, int n, int (*cmp)(void *p1, void *p2))

您现在在冒泡排序中比较为:

    int cmpResult = cmp(prs[j], prs[j+1]);

比较例程的签名是:

int cmpTwoPersons(struct person *a, struct person *b);

并将冒泡排序称为:

bubblesort(prs, n, cmpTwoPersons);

通过使用 void * 作为数据类型,您可以使冒泡排序算法独立于要排序的数据,比较函数说明如何比较两个元素。但是,要排序的数据必须是指针数组,因此气泡只需要交换指针而不是整个结构,因为它不知道它们的大小。

您可以使用与标准 C 函数使用的方法类似的方法 qsort

向函数添加第三个参数bubble_sort。例如

void bubble_sort( struct person *p,
                  int n, 
                  int comp( const struct person *p1, const struct person *p2 ) );

尽管将函数的第二个参数声明为类型 size_t

会好得多
void bubble_sort( struct person *p,
                  size_t n, 
                  int comp( const struct person *p1, const struct person *p2 ) );

然后定义两个比较struct person类型对象的函数。每个函数必须 return 如果第一项小于第二项,则为负值,如果第一项大于第二项,则为正值,否则为零。

函数看起来像

int comp_by_name( const struct person *p1, const struct person *p2 )
{
    int str_cmp = strcmp( p1->name, p2->name );
    int int_cmp = ( p2->age < p1->age ) - ( p1->age < p2->age );

    return str_cmp != 0 ? str_cmp : int_cmp;
}

int comp_by_age( const struct person *p1, const struct person *p2 )
{
    int str_cmp = strcmp( p1->name, p2->name );
    int int_cmp = ( p2->age < p1->age ) - ( p1->age < p2->age );

    return int_cmp != 0 ? int_cmp : str_cmp;
}

并在 bubble_sort 中写入以下 if 语句

if ( comp( &prs[j+1], &prs[j] ) < 0 )
{
    struct person tmp = prs[j+1];
    prs[j+1] = prs[j];
    prs[j] = tmp;
}

最后调用函数 bubble_sort 或者像

bubble_sort( prs, n, comp_by_name );

如果您想按名称对数组进行排序或

bubble_sort( prs, n, comp_by_age );

如果你想按年龄对数组进行排序。