parent
1d408183e1
commit
c43a9c437d
@ -0,0 +1,345 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
Loading…
Reference in new issue