鱼C论坛

 找回密码
 立即注册
查看: 1129|回复: 7

[已解决]大佬帮我看看单链表排序

[复制链接]
发表于 2021-10-30 09:28:15 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
问题是输入学生成绩按大到小输入,大的打印在最上面
我的思路按照不同情况分析:

1,当list是空的,把p=list。
2,当list不是空的,p最小,头指针先指向p,p指向原来的信息域
3,当list不是空的,p最大,先找到尾部的current,然后指向p
4,当list不是空的,p要插入中间,先找到比p大的第一个数为current,上一个数位previous,previous指向怕,p指向current

运行时第二种情况排序打印小的在上面
运行第三种输入两个数据后就自动结束了

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

struct Sorce
{
    int chinese;
    int math;
    int english;
};

struct Student
{
    int num;
    char name[20];
    struct Sorce sorce;
    float average;
    struct Student*next;
};

void getInput(struct Student*student);
void getInput(struct Student*student)
{
    printf("请输入学号");
    scanf("%d",&student->num);
    printf("请输入名字");
    scanf("%s",student->name);
    printf("请输入语文数学英语成绩");
    scanf("%d %d %d",&student->sorce.chinese,&student->sorce.math,&student->sorce.english);
    student->average=(student->sorce.chinese+student->sorce.math+student->sorce.english)/3;
}

void addStudent(struct Student**list);
void addStudent(struct Student**list)
{
    struct Student*previous;
    struct Student*current;
    struct Student*p;
    struct Student*temp;
    current=*list;
    previous=NULL;
    p=(struct Student*)malloc(sizeof(struct Student));
    if(p==NULL)
    {
        printf("内存分配失败\n");
        exit(1);
    }
    getInput(p);
    while(current!=NULL && (current->average)<(p->average))
    {
        previous=current;
        current=current->next;                  
    }
    if(current==NULL && previous==NULL)
    {
        *list=p;
    }
    else if(current!=NULL && previous==NULL)
    {
        temp=*list;
        *list=p;
        p->next=temp;
    }
    else if(current==NULL && previous!=NULL)
    {
        previous->next=p;
        p->next=NULL;
    }
    else
    {
        previous->next=p;
        p->next=current;
    }
}

void printStu(struct Student*list);
void printStu(struct Student*list)
{
    struct Student*current;
    current=list;
    while(current!=NULL)
    {
        printf("%d %s %d %d %d\n",current->num,current->name,current->sorce.chinese,current->sorce.math,current->sorce.english);
        current=current->next;
    }
    putchar('\n');
    free(current);
}
int main()
{
    struct Student*list=NULL;
    int ch;
    while(1)
    {
        printf("是否录入学生信息(Y/N)");
        do
        {
            ch=getchar();
        }
        while(ch!='Y' && ch!='N');
            if(ch=='Y')
        {
            addStudent(&list);
        }
        else
        {
                break;
        }
    }
    printStu(list);
    return 0;
}
最佳答案
2021-10-30 10:16:38
本帖最后由 jackz007 于 2021-10-30 19:39 编辑

        改写这个函数
void addStudent(struct Student**list)
【正序】
void addStudent(struct Student**list)
{
    struct Student * p , * p1 , * p2                  ;
    p=(struct Student*)malloc(sizeof(struct Student)) ;
    if(p==NULL)
    {
        printf("内存分配失败\n");
        exit(1);
    }
    getInput(p);
    for(p1 = p2 = * list ; p1 && p1 -> average < p -> average ; p2 = p1 , p1 = p2 -> next) ;
    if(p2) {
        if(p1 == * list) {
            p -> next = p2     ; // 新节点位于链头
            * list = p         ; 
        } else {
            p -> next = p1     ; // 新节点位于链中、链尾
            p2 -> next = p     ;
        }
    } else {
        p -> next = NULL       ; // 新建链表
        * list = p             ;
    }
}
【逆序】:
void addStudent(struct Student**list)
{
    struct Student * p , * p1 , * p2                  ;
    p=(struct Student*)malloc(sizeof(struct Student)) ;
    if(p==NULL)
    {
        printf("内存分配失败\n");
        exit(1);
    }
    getInput(p);
    for(p1 = p2 = * list ; p1 && p1 -> average > p -> average ; p2 = p1 , p1 = p2 -> next) ;
    if(p2) {
        if(p1 == * list) {
            p -> next = p2     ; // 新节点位于链头
             * list = p         ; 
        } else {
            p -> next = p1     ; // 新节点位于链中、链尾
            p2 -> next = p     ;
        }
    } else {
        p -> next = NULL       ; // 新建链表
        * list = p             ;
    }
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-10-30 09:29:16 | 显示全部楼层
本帖最后由 青衫烟雨客 于 2021-10-30 21:52 编辑

这道题题目是按照学号输入学生成绩,成绩不同,打印从成绩高到低,高的打印在最上面

第四种是previous指向p,p指向current
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-30 10:16:38 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2021-10-30 19:39 编辑

        改写这个函数
void addStudent(struct Student**list)
【正序】
void addStudent(struct Student**list)
{
    struct Student * p , * p1 , * p2                  ;
    p=(struct Student*)malloc(sizeof(struct Student)) ;
    if(p==NULL)
    {
        printf("内存分配失败\n");
        exit(1);
    }
    getInput(p);
    for(p1 = p2 = * list ; p1 && p1 -> average < p -> average ; p2 = p1 , p1 = p2 -> next) ;
    if(p2) {
        if(p1 == * list) {
            p -> next = p2     ; // 新节点位于链头
            * list = p         ; 
        } else {
            p -> next = p1     ; // 新节点位于链中、链尾
            p2 -> next = p     ;
        }
    } else {
        p -> next = NULL       ; // 新建链表
        * list = p             ;
    }
}
【逆序】:
void addStudent(struct Student**list)
{
    struct Student * p , * p1 , * p2                  ;
    p=(struct Student*)malloc(sizeof(struct Student)) ;
    if(p==NULL)
    {
        printf("内存分配失败\n");
        exit(1);
    }
    getInput(p);
    for(p1 = p2 = * list ; p1 && p1 -> average > p -> average ; p2 = p1 , p1 = p2 -> next) ;
    if(p2) {
        if(p1 == * list) {
            p -> next = p2     ; // 新节点位于链头
             * list = p         ; 
        } else {
            p -> next = p1     ; // 新节点位于链中、链尾
            p2 -> next = p     ;
        }
    } else {
        p -> next = NULL       ; // 新建链表
        * list = p             ;
    }
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-30 13:26:42 | 显示全部楼层
jackz007 发表于 2021-10-30 10:16
改写这个函数

【头插法】

大佬,我想问问这个函数为啥当第一个输入数据小于第二个输入数据时,会进入死循环
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-30 16:00:33 | 显示全部楼层
jackz007 发表于 2021-10-30 10:16
改写这个函数

【头插法】

大佬,这道题还有方法实现嘛
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-30 19:41:11 | 显示全部楼层
青衫烟雨客 发表于 2021-10-30 16:00
大佬,这道题还有方法实现嘛

       3 楼的代码已经更新,现在再试。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-30 21:06:01 | 显示全部楼层
jackz007 发表于 2021-10-30 19:41
3 楼的代码已经更新,现在再试。

可以了,非常感谢,麻烦您了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-30 21:48:43 | 显示全部楼层
本帖最后由 青衫烟雨客 于 2021-10-30 21:56 编辑

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-22 19:32

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表