#include #include #include #include #define MAX_NAME_LENGTH 50 #define SUBJECTS_COUNT 3 typedef struct { char id[20]; char name[MAX_NAME_LENGTH]; float scores[SUBJECTS_COUNT]; float total; } Student; typedef struct LNode { Student data; struct LNode* next; } LNode, *LinkList; bool InitList(LinkList* L); bool DestroyList(LinkList* L); bool ClearList(LinkList* L); bool ListEmpty(LinkList L); int ListLength(LinkList L); bool GetElem(LinkList L, int i, Student* e); int LocateElemById(LinkList L, const char* id); bool ListInsert(LinkList* L, int i, const Student* e); bool ListDelete(LinkList* L, int i); void TraverseList(LinkList L); void PrintStudent(const Student* s); void InputStudent(Student* s); void SortListByTotal(LinkList* L); // 菜单函数 void showMenu() { printf("\n===== 学生成绩管理系统 =====\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("===========================\n"); printf("请输入你的选择: "); } // 计算总分 void calculateTotal(Student* s) { s->total = 0; for (int i = 0; i < SUBJECTS_COUNT; i++) { s->total += s->scores[i]; } } // 打印学生信息 void PrintStudent(const Student* s) { printf("学号:%s\n", s->id); printf("姓名:%s\n", s->name); printf("成绩:"); for (int i = 0; i < SUBJECTS_COUNT; i++) { switch (i) { case 0: printf("语文: %.1f ", s->scores[i]); break; case 1: printf("数学: %.1f ", s->scores[i]); break; case 2: printf("英语: %.1f ", s->scores[i]); break; default: break; } } printf("总分: %.1f\n", s->total); } // 输入学生信息 void InputStudent(Student* s) { printf("请输入学号: "); scanf("%s", s->id); printf("请输入姓名: "); scanf("%s", s->name); for (int i = 0; i < SUBJECTS_COUNT; i++) { switch (i) { case 0: printf("请输入语文科目成绩: "); scanf("%f", &s->scores[i]); break; case 1: printf("请输入数学成绩: "); scanf("%f", &s->scores[i]); break; case 2: printf("请输入英语成绩: "); scanf("%f", &s->scores[i]); break; default: break; } } calculateTotal(s); // 计算总分 } // 链表基本操作实现 bool InitList(LinkList* L) { *L = (LNode*)malloc(sizeof(LNode)); if (*L == NULL) return false; (*L)->next = NULL; return true; } bool DestroyList(LinkList* L) { LNode* p; while (*L != NULL) { p = *L; *L = (*L)->next; free(p); } return true; } bool ClearList(LinkList* L) { LNode *p, *q; p = (*L)->next; while (p != NULL) { q = p; p = p->next; free(q); } (*L)->next = NULL; return true; } bool ListEmpty(LinkList L) { return L->next == NULL; } int ListLength(LinkList L) { int len = 0; LNode* p = L->next; while (p != NULL) { len++; p = p->next; } return len; } bool GetElem(LinkList L, int i, Student* e) { if (i < 1) return false; int j = 1; LNode* p = L->next; while (p != NULL && j < i) { p = p->next; j++; } if (p == NULL) return false; *e = p->data; return true; } int LocateElemById(LinkList L, const char* id) { int pos = 1; LNode* p = L->next; while (p != NULL) { if (strcmp(p->data.id, id) == 0) { return pos; } p = p->next; pos++; } return 0; } bool ListInsert(LinkList* L, int i, const Student* e) { if (i < 1) return false; int j = 0; LNode *p = *L, *s; while (p != NULL && j < i - 1) { p = p->next; j++; } if (p == NULL) return false; s = (LNode*)malloc(sizeof(LNode)); if (s == NULL) return false; s->data = *e; // 复制学生数据 s->next = p->next; p->next = s; return true; } bool ListDelete(LinkList* L, int i) { if (i < 1) return false; int j = 0; LNode *p = *L, *q; while (p->next != NULL && j < i - 1) { p = p->next; j++; } if (p->next == NULL) return false; q = p->next; p->next = q->next; free(q); return true; } // 修正 TraverseList 函数 void TraverseList(LinkList L) { LNode* p = L->next; while (p != NULL) { PrintStudent(&p->data); printf("-----------------\n"); p = p->next; } } // 按总分降序排序(冒泡排序) void SortListByTotal(LinkList* L) { int len = ListLength(*L); if (len <= 1) return; for (int i = 0; i < len - 1; i++) { LinkList p = *L; for (int j = 0; j < len - i - 1; j++) { if (p->next->data.total < p->next->next->data.total) { // 交换节点数据 Student temp = p->next->data; p->next->data = p->next->next->data; p->next->next->data = temp; } p = p->next; } } } int main() { LinkList L; int choice, pos; Student s; char searchId[20]; InitList(&L); do { showMenu(); scanf("%d", &choice); getchar(); // 清除缓冲区的换行符 switch (choice) { case 1: // 添加学生 InputStudent(&s); if (LocateElemById(L, s.id) > 0) { printf("错误:学号已存在!\n"); break; } if (ListInsert(&L, ListLength(L) + 1, &s)) printf("添加成功!\n"); else printf("添加失败!\n"); break; case 2: // 删除学生 printf("请输入要删除的学生学号: "); scanf("%s", searchId); pos = LocateElemById(L, searchId); if (pos > 0) { if (ListDelete(&L, pos)) printf("删除成功!\n"); else printf("删除失败!\n"); } else { printf("未找到该学生!\n"); } break; case 3: // 查询学生 printf("请输入要查询的学生学号: "); scanf("%s", searchId); pos = LocateElemById(L, searchId); if (pos > 0) { GetElem(L, pos, &s); PrintStudent(&s); } else { printf("未找到该学生!\n"); } break; case 4: // 修改学生信息 printf("请输入要修改的学生学号: "); scanf("%s", searchId); pos = LocateElemById(L, searchId); if (pos > 0) { GetElem(L, pos, &s); printf("当前学生信息:\n"); PrintStudent(&s); printf("请输入新的学生信息:\n"); InputStudent(&s); ListDelete(&L, pos); ListInsert(&L, pos, &s); printf("修改成功!\n"); } else { printf("未找到该学生!\n"); } break; case 5: // 显示所有学生 if (ListEmpty(L)) { printf("暂无学生信息!\n"); } else { printf("所有学生信息如下:\n"); TraverseList(L); } break; case 6: // 按总分排序 if (ListEmpty(L)) { printf("暂无学生信息!\n"); } else { SortListByTotal(&L); printf("已按总分从高到低排序!\n"); TraverseList(L); } break; case 7: // 统计学生人数 printf("当前系统共有 %d 名学生。\n", ListLength(L)); break; case 0: // 退出系统 printf("感谢使用学生成绩管理系统,再见!\n"); break; default: printf("无效的选择,请重新输入!\n"); } } while (choice != 0); DestroyList(&L); return 0; }