大一新手,请教,学生管理系统的程序

麻烦帮忙看看,万分感谢。
用c语言写的链表,主要是排名那个函数不知哪里出了问题,排不出正确结果。

下面是源代码:

#include
#include
#include
typedef struct n{
    char number[15];
    char name[10];
    int a;
    int b;
    int c;
    struct n* next;
}bin;
int luru(bin *q){//q是头节点。 
    printf("您需要录入几个学生:");
    int a;
    scanf("%d",&a);
    while(a)
        {
        bin *s = (bin *)malloc(sizeof(bin));
        printf("请输入学号(小于15个字节):");
        scanf("%s",&s->number);
        printf("请输入学生姓名(小于10个字节):");
        scanf("%s",&s->name);
        printf("请输入第一门成绩:");
        scanf("%d",&s->a);
        printf("请输入第二门成绩:");
        scanf("%d",&s->b);
        printf("请输入第三门成绩:");
        scanf("%d",&s->c); 
        s->next = q->next;
        q->next = s;
        printf("录入成功。\n");
        a--;
        }
    return 1;
}
int panduan(bin *z,bin *a[],int n){//数组里出现过了的地址,就不再存放; 
    for(int i = 0;i <= n;i++)
        {
        if(z == a[i])
            return 0;
        }
    return 1;
}
int paiming(bin *q){//对链表按总成绩排名。 
    if(q->next == 0)
        {
        printf("没有学生的信息。\n");
        return 0;
        }     
    bin *p = q->next,*z;
    int i = 0,max = 0,n = -1;
    while(p != 0)
        {
        i++;
        p = p->next; 
        }
    bin *a[i];//用一个数组,总成绩从大到小的存放链表地址。 
    while(n < i)
        {
        p = q->next;
        while(p != 0)
            {
            if((p->a + p->b + p->c) >= max&&panduan(z,a,n))//如果重复地址就不进入。 
                {
                max = p->a + p->b + p->c;
                z = p;
                }
            p = p->next;
            }
        n++;
        a[n] = z;
        }
    for(n = 0;n < i;n++)
        {
         printf("学生学号:%s    学生姓名:%s\n",a[n]->number,a[n]->name);
        }
    return 1;
}
int main()
{
    bin *q = (bin *)malloc(sizeof(bin));
    q->next = 0;
    luru(q);
    paiming(q);
}

我的思路是:
我用循环,第一次找出链表中最大的总成绩,并将它的地址放进数组下表0的位置。从第二次开始,还是用循环找到最大值(panduan函数用来保证相同一个结点只算一次),一直循环,直到数组元素个数等于链表长度,就结束循环,最后用数组里的地址依次打印。
程序不能达到想要的效果,这个程序我主要是想用数组存放地址,因为我不想改变原先链表的顺序,我也很知道我到底错在哪里。希望有人指正。非常感谢,谢谢。

在你的排名函数中,while(n < i)的循环体中,每次循环完需要把max = 0; z = null, 需要把它们复位,不然在一次循环完之后,找到了最大值max, 后面不会有比max更大的情况了。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/7486456
  • 除此之外, 这篇博客: C语言实现八大排序算法详解及其性能之间的中的 我们老师给我们花了100个星星的重要,那就是非常重要,快速排序。名字就很嚣张。。。言归正传,快排采用了分治算法。把大问题,分解成小问题。首先我们先找一个基准值,基准值的寻找法,有很多,这里我先用一个取边上值得方法,找到基准值以后呢拿着这个基准值和所有数组比较,使这个数组中比基准值小的都放左边,比基准值大的都放到右边,然后就把原来数组分成三块,中间基准值,左边都是比它小的,右边都是比它大的。然后这两个数组,继续分,一直分。直到他的终止条件,也就是小数组有序了就停止,那么什么时候有序停止呢?小区间长度为1或者长度为0的时候,就是有序了。所有小数组都有序了,那么就是整个数组有序了。只是原理,那么问题,又来了,怎么放左放右呢?我目前会三种。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    算法思想


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^