求解一下,为什么插入数据之后无法排序

这是一个学生成绩管理系统,其中有链表的储存结构,其他都正常,但是在“插入并排序”这里出了问题,插入之后并没有排序,希望能解答一下。

img

img

img

img

img

img

img

img

排序代码错了,明显不可能一个 while 循环就排序

你自己 google 下链表排序的思路

  • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/7612682
  • 这篇博客你也可以参考下:有15个数按由大到小顺序存放在一个数组中,输入一个数,要求用折半查找法找出该数是数组中 第几个元素的值。如果该数不在数组中,则输出“无此数”。
  • 除此之外, 这篇博客: 一个数组,把奇数放到左边,偶数放到右边,调整后有序方法和无序方法中的 2、有序 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 有序是指奇数的相对位置不变,偶数的相对位置也不变

    void orderSort(int a[])
    {
        int i, j, k, x;
        for (i = 0; ; i++)
        {
            while (a[i] % 2) i++; //找到从左到右第一个偶数
            j = i + 1;
            while (!(a[j] % 2)) j++; //找到该偶数右边第一个奇数
            if(j > 9) break; //便利完退出循环
            for (x = j; x > i; x--) //向左冒一次泡(大概这个意思)
            {
                k = a[x];
                a[x] = a[x - 1];
                a[x - 1] = k;
            }
            printfArray(a);
        }
    }
    
  • 您还可以看一下 刘建萍老师的人工智能系列课程零基础讲解知识点和实例应用线性回归梯度下降逻辑回归课程中的 讲解机器学中会涉及到的有关数学方面的知识储备有哪些小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    对于学生成绩管理系统中插入数据后无法排序的问题,您可以尝试以下解决方案:

    1. 确保链表中的数据结构包含成绩字段。例如,可以定义一个名为"Student"的结构体,包含成绩字段。每个节点即为一个学生的数据。
    typedef struct {
        char name[50];
        int score;
    } Student;
    
    1. 插入数据后,遍历链表,找到插入位置并进行排序。可以按照以下步骤进行:
    // 声明一个指向链表头的指针
    Node *head;
    
    // 定义一个新的节点,并为其分配空间
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->data = newStudent;  // newStudent为要插入的学生数据
    
    // 如果链表为空或新节点的成绩比头节点的成绩大,则将新节点作为新的头节点
    if(head == NULL || newStudent.score > head->data.score) {
        newNode->next = head;
        head = newNode;
    }
    else {
        // 遍历链表找到新节点的插入位置
        Node *current = head;
        while(current->next != NULL && newStudent.score <= current->next->data.score) {
            current = current->next;
        }
        // 插入新节点
        newNode->next = current->next;
        current->next = newNode;
    }
    
    1. 完整的代码示例:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct {
        char name[50];
        int score;
    } Student;
    
    typedef struct Node {
        Student data;
        struct Node *next;
    } Node;
    
    void insertSorted(Node **head, Student newStudent) {
        Node *newNode = (Node *)malloc(sizeof(Node));
        newNode->data = newStudent;
    
        if(*head == NULL || newStudent.score > (*head)->data.score) {
            newNode->next = *head;
            *head = newNode;
        }
        else {
            Node *current = *head;
            while(current->next != NULL && newStudent.score <= current->next->data.score) {
                current = current->next;
            }
            newNode->next = current->next;
            current->next = newNode;
        }
    }
    
    void printList(Node *head) {
        Node *current = head;
        while(current != NULL) {
            printf("Name: %s, Score: %d\n", current->data.name, current->data.score);
            current = current->next;
        }
    }
    
    int main() {
        Node *head = NULL;
    
        Student student1 = {"Alice", 80};
        insertSorted(&head, student1);
    
        Student student2 = {"Bob", 95};
        insertSorted(&head, student2);
    
        Student student3 = {"Charlie", 70};
        insertSorted(&head, student3);
    
        Student student4 = {"David", 85};
        insertSorted(&head, student4);
    
        printList(head);
    
        return 0;
    }
    

    这样,插入数据后链表会按照成绩从高到低的顺序进行排序。

    希望以上解决方案能够帮助您解决问题。如果还有其他疑问,请随时提出。

struct student students[50]; //学生数组 struct node *head = NULL; // 链表头指针
定义了两种数据结构,录入学生信息函数 int input_students() 里只有对数组students[50];的操作, 和链表没什么关系,也没生成链表。然后在 插入学生信息函数 int insert_students() 里又对链表进行操作,此时链表是空链表,即使插入成功了,这个链表只有一个结点,且和数组 students[50]无关,它也不需要排序。
整体修改完善如下,改动处见注释,供参考。查询里 按分数段查询写法有问题,不能实现功能,留给题主解决。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义学生结构体
struct student {
    char id[20]; // 学号 
    char name[20]; // 姓名 
    char Class[20]; // 班级  //char class[20];  修改
    int  math; // 高数成绩 
    int  eng; // 英语成绩 
    int  total; // 总成绩
};
// 定义链表节点结构体
struct node {
    struct student stu;
    struct node* next;
};
// 定义全局变量
int count = 0; // 记录学生人数
struct student students[50]; // 学生数组
struct node* head = NULL; // 链表头指针

int input_students();
int sort_by_id();
int insert_students();
int delete_students();
int search_students();
int statistics();
int output_students();

void insert_node(struct student stu);   //  修改

// 主函数
int main()
{
    // 显示菜单 
    int choice;
    while (1) {
        printf("===========================\n");
        printf(" 菜单 \n");
        printf("===========================\n");
        printf("[1] 录入学生信息\n");
        printf("[2] 按学号排序\n");
        printf("[3] 插入学生信息\n");
        printf("[4] 删除学生信息\n");
        printf("[5] 查询学生信息\n");
        printf("[6] 统计成绩\n");
        printf("[7] 输出所有学生信息\n");
        printf("[0] 退出程序\n");
        printf("请选择操作:");
        scanf("%d", &choice); // 执行对应操作 
        switch (choice) {
        case 1: input_students();
            break;
        case 2: sort_by_id();
            break;
        case 3: insert_students();
            break;
        case 4: delete_students();
            break;
        case 5: search_students();
            break;
        case 6: statistics();
            break;
        case 7: output_students();
            break;
        case 0: printf("程序已退出.\n");
            return 0;
        default: printf("无效操作,请重新选择.\n");
            break;
        }
    }
    return 0;
}

// 链表按学号降序插入
void insert_node(struct student stu)     //  修改
{
    struct node* p = head;
    struct node* prev = NULL;
    struct node* new_node = (struct node*)malloc(sizeof(struct node));
    new_node->stu = stu;
    new_node->next = NULL;
    while (p != NULL && strcmp(p->stu.id, stu.id) > 0)
    {
        prev = p;
        p = p->next;
    }
    if (prev == NULL) {
        new_node->next = head;
        head = new_node;
    }
    else {
        prev->next = new_node;
        new_node->next = p;
    }
}

// 录入学生信息
int input_students()
{
    printf("请输入学生信息(输入-1结束):\n");
    while (1) {
        // 判断是否结束录入 
        if (count == 50) {
            printf("学生人数已达到最大值50人,录入终止.\n");
            break;
        }
        char id[20];
        printf("学号:");
        scanf("%s", id);
        if (strcmp(id, "-1") == 0) {
            printf("学生信息录入完毕.\n");
            break;
        }
        int i;
        for (i = 0; i < count; i++) { // 判断是否已存在该学生信息 
            if (strcmp(students[i].id, id) == 0) {
                printf("该学号已存在,请重新输入.\n");
                break;
            }
        }
        if (i == count) {
            strcpy(students[count].id, id);
            printf("姓名:");
            scanf("%s", students[count].name);
            printf("班级:");
            scanf("%s", students[count].Class);
            printf("高数成绩:");
            scanf("%d", &students[count].math);
            printf("英语成绩:");
            scanf("%d", &students[count].eng);
            students[count].total = students[count].math + students[count].eng; // 计算总成绩 
            insert_node(students[count]);                       //  修改
            count++;
            printf("学生信息录入成功.\n");
        }
    } return 0;
}
// 按学号排序
int sort_by_id()
{
    int i, j;
    struct student temp;
    for (i = 0; i < count - 1; i++) {
        for (j = 0; j < count - 1 - i; j++) {
            if (strcmp(students[j].id, students[j + 1].id) < 0) {
                temp = students[j];
                students[j] = students[j + 1];
                students[j + 1] = temp;
            }
        }
    }
    printf("按学号排序成功.\n");
    return 0;
}
// 插入学生信息
int insert_students()
{ // 读取要插入的学生信息 
    int i, j;
    struct student new_stu;
    printf("请输入要插入的学生信息:\n");
    printf("学号:");
    scanf("%s", new_stu.id);
    for (i = 0; i < count; i++) { // 判断是否已存在该学号      修改
        if (strcmp(students[i].id, new_stu.id) == 0) {
            printf("该学号已存在,插入失败.\n");
            return 1;     //   修改
        }
    }
    printf("姓名:");
    scanf("%s", new_stu.name);
    printf("班级:");
    scanf("%s", new_stu.Class);
    printf("高数成绩:");
    scanf("%d", &new_stu.math);
    printf("英语成绩:");
    scanf("%d", &new_stu.eng);
    new_stu.total = new_stu.math + new_stu.eng; // 计算总成绩 
    
    students[count++] = new_stu;    // 修改
    // 插入节点并排序 
    insert_node(new_stu);          //  修改 

    printf("学生信息插入成功.\n");
    return 0;
}
// 删除学生信息
int delete_students()
{
    char id[20];
    printf("请输入要删除的学生学号:");
    scanf("%s", id);
    // 在数组中查找并删除 
    int i, j;
    for (i = 0; i < count; i++) {
        if (strcmp(students[i].id, id) == 0) {
            for (j = i; j < count - 1; j++) {
                students[j] = students[j + 1];
            }
            count--;
            printf("学生信息删除成功.\n");
        }
    }
    // 在链表中查找并删除 
    struct node* p = head;
    struct node* prev = NULL;
    while (p != NULL && strcmp(p->stu.id, id) != 0)
    {
        prev = p;
        p = p->next;
    }
    if (p == NULL) {
        printf("未找到该学号对应的学生信息,删除失败.\n");
    }
    else {
        if (prev == NULL) {
            head = p->next;
        }
        else {
            prev->next = p->next;
        }
        free(p);
        printf("学生信息删除成功.\n");
    }
    return 0;
}
// 查询学生信息
int search_students()
{
    int choice;
    printf("===========================\n");
    printf(" 查询菜单 \n"); 
    printf("===========================\n");
    printf("[1] 按学号查询\n");
    printf("[2] 按姓名查询\n");
    printf("[3] 按分数段查询\n");
    printf("请选择查询方式:");
    scanf("%d", &choice);
    switch (choice) {
    case 1: {
        char id[20];
        printf("请输入要查询的学生学号:");
        scanf("%s", id);
        int i;
        for (i = 0; i < count; i++) {
            if (strcmp(students[i].id, id) == 0) {
                printf("学号\t姓名\t班级\t高数\t英语\t总成绩\n");
                printf("%s\t%s\t%s\t%d\t%d\t%d\n", students[i].id, students[i].name, 
                    students[i].Class, students[i].math, students[i].eng, students[i].total);
                break;
            }
        }
        if (i == count)
            printf("未找到该学号对应的学生信息.\n");
        break; 
    }
    case 2: {
        char name[20];
        printf("请输入要查询的学生姓名:");
        scanf("%s", name);
        int i;
        for (i = 0; i < count; i++) {
            if (strcmp(students[i].name, name) == 0) {
                printf("学号\t姓名\t班级\t高数\t英语\t总成绩\n");
                printf("%s\t%s\t%s\t%d\t%d\t%d\n", students[i].id, students[i].name, 
                    students[i].Class, students[i].math, students[i].eng, students[i].total);
                break;
            }
        }
        if (i == count)
            printf("未找到该姓名对应的学生信息.\n");
        break; 
    }
    case 3: {
        int section;
        printf("请输入分数段(每隔10分为一个段):");
        scanf("%d", &section);
        int i, j;
        for (i = 0; i <= 100; i += 10) {
            if (section == i) {
                printf("成绩在%d~%d分之间的学生有:\n", i, i + 9);
                printf("学号\t姓名\t班级\t高数\t英语\t总成绩\n");
                for (j = 0; j < count; j++) {
                    if (students[j].total >= i && students[j].total <= i + 9) {
                        printf("%s\t%s\t%s\t%d\t%d\t%d\n", students[j].id, students[j].name, 
                            students[j].Class, students[j].math, students[j].eng, students[j].total);
                    }
                }
            }
        }
        printf("无效分数段,请重新查询.\n");
        break; 
    }
    default:
        printf("无效查询方式,请重新选择.\n");
        break;
    }
    return 0;
}
// 统计成绩
int statistics()
{
    int math_total = 0, eng_total = 0, total_total = 0; // 各科总分 
    int i;
    for (i = 0; i < count; i++) {
        math_total += students[i].math;
        eng_total += students[i].eng;
        total_total += students[i].total;
    }
    float math_avg = (float)math_total / count; // 高数平均分 
    float eng_avg = (float)eng_total / count; // 英语平均分 
    float total_avg = (float)total_total / count; // 总成绩平均分 
    printf("高数总分:%d,平均分:%.2f\n", math_total, math_avg);
    printf("英语总分:%d,平均分:%.2f\n", eng_total, eng_avg);
    printf("总成绩总分:%d,平均分:%.2f\n", total_total, total_avg);
    return 0;
}
// 输出所有学生信息
int output_students()
{
    printf("学号\t姓名\t班级\t高数\t英语\t总成绩\n");
    int i;
    for (i = 0; i < count; i++) {
        printf("%s\t%s\t%s\t%d\t%d\t%d\n", students[i].id, students[i].name, 
            students[i].Class, students[i].math, students[i].eng, students[i].total);
    }
    struct node* p = head;
    while (p != NULL) {
        printf("%s\t%s\t%s\t%d\t%d\t%d\n", p->stu.id, p->stu.name, 
               p->stu.Class, p->stu.math, p->stu.eng, p->stu.total);
        p = p->next;
    }
    return 0;
}