【问题标题】:Bubblesort algorithm with Function Pointers in CC语言中带有函数指针的冒泡排序算法
【发布时间】:2017-02-19 10:10:48
【问题描述】:

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

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

#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]='\0';
    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;
 }

【问题讨论】:

  • 看qsort的原型。它应该为您提供足够的提示,让您了解如何编写通用的排序函数。
  • 我不能使用 qsort。我已经知道如何使用 qsort。我不得不创建这个冒泡排序函数,而不是 qsort。
  • 我没说你使用 qsort。我说你研究它是如何定义的,这样你就可以编写自己的排序函数,天哪......

标签: c algorithm sorting function-pointers bubble-sort


【解决方案1】:

您可以使用类似于标准 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 类型的对象。如果第一项小于第二项,则每个函数必须返回负值,如果第一项大于第二项,则返回正值,否则返回零。

函数看起来像

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 );

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

【讨论】:

    【解决方案2】:

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

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

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

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

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

    使用此比较函数调用您的冒泡排序:

    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
        }
        ...
    }
    

    【讨论】:

    • 非常感谢!我发现您的回答很有帮助,我完全理解。现在的问题是,当比较函数返回 0 时,我应该调用另一个函数。我应该声明指针函数数组,然后将 cmp 与元素进行比较,然后选择不一样的元素吗?
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2018-05-25
      • 2017-06-21
      • 2014-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-11
      相关资源
      最近更新 更多