让结构体按某一个属性排序,减少排序函数复用,怎么弄?

2020-12-04 22:25发布

问题:

题目:

给出n个学生的考试成绩信息,每条信息由学号、姓名与分数组成。要求首先按学号对信息进行排序,然后再按分数进行排序,并要求分数相同的仍然按学号有序,输出每次排序的结果。

 

存储方式用的是结构体数组,写好排序函数以后发现题目说要分别按学号和分数排序,如果按简单思路的话就是一个排序用一个函数,只改了一处地方,感觉很亢余:

 

 printf("按学号排序:\n");
    SelectSortbyOrder(student);
    for(p=student;(p+1)->score!='\000';p++)
    {
        printf("学号:%d\n姓名:%s\n分数:%d\n地址:%p\n\n",p->order,p->name,p->score,p);
    }
    printf("\n");

    printf("再按分数排序:\n");
    SelectSortbyScore(student);
    for(p=student;(p+1)->score!='\000';p++)
    {
        printf("学号:%d\n姓名:%s\n分数:%d\n地址:%p\n\n",p->order,p->name,p->score,p);
    }
    printf("\n");
    return 0;

 

于是想修改排序算法的代码让其能按照结构体的某个属性来排序

直接的想法就是通过函数传入对应语句,但在C中要如何实现?

 

代码:

#include <stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
struct  Students
{
    int order;
    char *name;
    int score;

};

typedef struct Students Stu;
void swap(Stu *a,Stu *b)
{
    Stu temp;

    temp.order  =   a->order;
    temp.name   =   a->name ;
    temp.score  =   a->score;

    a->order     =   b->order;
    a->name      =   b->name ;
    a->score     =   b->score;

    b->order     =   temp.order;
    b->name      =   temp.name ;
    b->score     =   temp.score;
}

void SelectSortbyOrder(Stu *p)   //用选择排序来排序
{
    Stu *min = p;
    Stu *head = p;
    while((head+1)->score!='\000')
    {
        while((p+1)->score!='\000')
        {
            if(p->order < min->order)
            {
                min = p;
            }
            p++;
        }
        // printf("最小学号:%d\n",min->order);
        swap(head,min);
        head++;
        min = head;
        p = head;
    }
  
        
}

void SelectSortbyScore(Stu *p)   //用选择排序来排序
{
    Stu *min = p;
    Stu *head = p;
    while((head+1)->score!='\000')
    {
        while((p+1)->score!='\000')
        {
            if(p->score < min->score)
            {
                min = p;
            }
            p++;
        }
        // printf("最小学号:%d\n",min->order);
        swap(head,min);
        head++;
        min = head;
        p = head;
    }
  
        
}

void SelectSort(Stu *p,int *value)   //用选择排序来排序
{
    Stu *min = p;
    Stu *head = p;
    while((head+1)->score!='\000')
    {
        while((p+1)->score!='\000')
        {
            if(p->score < min->score)
            {
                min = p;
            }
            p++;
        }
        // printf("最小学号:%d\n",min->order);
        swap(head,min);
        head++;
        min = head;
        p = head;
    }
  
        
}

int main()
{
    Stu student[3];
    Stu *p;
    int i=0;
    student[0].order = 402; //  初始化
    student[0].name = "zdz";
    student[0].score = 79;

    student[1].order = 403; 
    student[1].name = "zdl";
    student[1].score = 62;

    student[2].order = 401; 
    student[2].name = "zxl";
    student[2].score = 83;

    printf("初始记录:\n");
    for(p=student;(p+1)->score!='\000';p++)
    {
        printf("学号:%d\n姓名:%s\n分数:%d\n结构体地址:%p\n学号地址:%p\n姓名地址:%p\n分数地址:%p\n\n",p->order,p->name,p->score,p,p->order,p->name,p->score);
    }

    printf("按学号排序:\n");
    SelectSort(student,&student->order);
    for(p=student;(p+1)->score!='\000';p++)
    {
        printf("学号:%d\n姓名:%s\n分数:%d\n地址:%p\n\n",p->order,p->name,p->score,p);
    }
    printf("\n");

    printf("再按分数排序:\n");
    SelectSort(student,&student->score);
    for(p=student;(p+1)->score!='\000';p++)
    {
        printf("学号:%d\n姓名:%s\n分数:%d\n地址:%p\n\n",p->order,p->name,p->score,p);
    }
    printf("\n");
    return 0;
}

 

#include <stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
struct  Students
{
    int order;
    char *name;
    int score;

};

typedef struct Students Stu;
void swap(Stu *a,Stu *b)
{
    Stu temp;

    temp.order  =   a->order;
    temp.name   =   a->name ;
    temp.score  =   a->score;

    a->order     =   b->order;
    a->name      =   b->name ;
    a->score     =   b->score;

    b->order     =   temp.order;
    b->name      =   temp.name ;
    b->score     =   temp.score;
}

void SelectSortbyOrder(Stu *p)   //用选择排序来排序
{
    Stu *min = p;
    Stu *head = p;
    while((head+1)->score!='\000')
    {
        while((p+1)->score!='\000')
        {
            if(p->order < min->order)
            {
                min = p;
            }
            p++;
        }
        // printf("最小学号:%d\n",min->order);
        swap(head,min);
        head++;
        min = head;
        p = head;
    }
  
        
}

void SelectSortbyScore(Stu *p)   //用选择排序来排序
{
    Stu *min = p;
    Stu *head = p;
    while((head+1)->score!='\000')
    {
        while((p+1)->score!='\000')
        {
            if(p->score < min->score)
            {
                min = p;
            }
            p++;
        }
        // printf("最小学号:%d\n",min->order);
        swap(head,min);
        head++;
        min = head;
        p = head;
    }
  
        
}

void SelectSort(Stu *p,int *value)   //用选择排序来排序
{
    Stu *min = p;
    Stu *head = p;
    while((head+1)->score!='\000')
    {
        while((p+1)->score!='\000')
        {
            if(p->score < min->score)
            {
                min = p;
            }
            p++;
        }
        // printf("最小学号:%d\n",min->order);
        swap(head,min);
        head++;
        min = head;
        p = head;
    }
  
        
}

int main()
{
    Stu student[3];
    Stu *p;
    int i=0;
    student[0].order = 402//  初始化
    student[0].name = "zdz";
    student[0].score = 79;

    student[1].order = 403
    student[1].name = "zdl";
    student[1].score = 62;

    student[2].order = 401
    student[2].name = "zxl";
    student[2].score = 83;

    printf("初始记录:\n");
    for(p=student;(p+1)->score!='\000';p++)
    {
        printf("学号:%d\n姓名:%s\n分数:%d\n结构体地址:%p\n学号地址:%p\n姓名地址:%p\n分数地址:%p\n\n",p->order,p->name,p->score,p,p->order,p->name,p->score);
    }

    printf("按学号排序:\n");
    SelectSort(student,&student->order);
    for(p=student;(p+1)->score!='\000';p++)
    {
        printf("学号:%d\n姓名:%s\n分数:%d\n地址:%p\n\n",p->order,p->name,p->score,p);
    }
    printf("\n");

    printf("再按分数排序:\n");
    SelectSort(student,&student->score);
    for(p=student;(p+1)->score!='\000';p++)
    {
        printf("学号:%d\n姓名:%s\n分数:%d\n地址:%p\n\n",p->order,p->name,p->score,p);
    }
    printf("\n");
    return 0;
}

回答1:

#include <stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
struct  Students
{
    int order;
    char *name;
    int score;

};

typedef struct Students Stu;
void swap(Stu *a,Stu *b)
{
    Stu temp;

    temp.order  =   a->order;
    temp.name   =   a->name ;
    temp.score  =   a->score;

    a->order     =   b->order;
    a->name      =   b->name ;
    a->score     =   b->score;

    b->order     =   temp.order;
    b->name      =   temp.name ;
    b->score     =   temp.score;
}

void SelectSort(Stu *p,int choose)   //用选择排序来排序
{
    Stu *min = p;
    Stu *head = p;
    while((head+1)->score!='\000')
    {
        while((p+1)->score!='\000')
        {
            if(choose == 0)
            {
                if(p->order < min->order)
                {
                    min = p;
                }
            }
           else if (choose == 1)
           {
               if(p->score < min->score)
                {
                    min = p;
                }
           }
           
            p++;
        }
        // printf("最小学号:%d\n",min->order);
        if(head->score > min->score)
            swap(head,min);
        head++;
        min = head;
        p = head;
    }
  
        
}

int main()
{
    Stu student[3];
    Stu *p;
    int i=0;
    student[0].order = 402; //  初始化
    student[0].name = "zdz";
    student[0].score = 79;

    student[1].order = 403; 
    student[1].name = "zdl";
    student[1].score = 62;

    student[2].order = 401; 
    student[2].name = "zxl";
    student[2].score = 83;

    printf("初始记录:\n");
    for(p=student;(p+1)->score!='\000';p++)
    {
        printf("学号:%d\n姓名:%s\n分数:%d\n地址:%p\n\n",p->order,p->name,p->score,p);
    }

    printf("按学号排序(输入 0):\n");
    SelectSort(student,0);
    for(p=student;(p+1)->score!='\000';p++)
    {
        printf("学号:%d\n姓名:%s\n分数:%d\n地址:%p\n\n",p->order,p->name,p->score,p);
    }
    printf("\n");

    printf("再按分数排序(输入 1):\n");
    SelectSort(student,1);
    for(p=student;(p+1)->score!='\000';p++)
    {
        printf("学号:%d\n姓名:%s\n分数:%d\n地址:%p\n\n",p->order,p->name,p->score,p);
    }
    printf("\n");
    return 0;
}

@Conan-jine 已自己解决,其实你想表达的思想是用布尔值做判断条件来使用哪个语句,但是本来就可以用if封装语句,没必要再设两个函数那么麻烦。



回答2:

如果是我的话,我会参考C++的sort()函数。

定义cmp1和cmp2函数,放入的都是结构体参数,如:bool cmp1(Stu *P, Stu *q);

然后只需要写一句返回语句就行了,分别是:
return p->score < q->score;

return p->order < q->order;

然后原来的if(---)变成 if(cmp1)或者if(cmp2)。

排序函数放入的参数为 sort(Stu *p, Stu *q, bool cmp);

 

可能我没有理解的你的代码思路,但是思想就是这。写比较函数就行了