利用尾插法建立一个单链表(要带表头),要求包含学生姓名,学号, 语文、数学、英语三门成绩等信息,计算总分,按从大到小的分数输出学生数据,并能够完成查找删除(按照姓名进行)功能。 (利用模块化设计的原则进行设计,必须调用子函数)
时间: 2024-06-09 11:09:28 浏览: 140
C实现单链表的头插法和尾插法来构建单链表.zip
好的,我可以给你提供代码实现,需要你在自己的环境中进行编译运行。代码如下:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 20
// 学生结构体
typedef struct student {
char name[MAX_LEN];
char id[MAX_LEN];
float chinese;
float math;
float english;
float total;
struct student *next;
} Student;
// 添加学生信息
void addStudent(Student **head) {
Student *newNode = (Student *) malloc(sizeof(Student));
printf("请输入学生姓名:\n");
scanf("%s", newNode->name);
printf("请输入学生学号:\n");
scanf("%s", newNode->id);
printf("请输入学生语文成绩:\n");
scanf("%f", &newNode->chinese);
printf("请输入学生数学成绩:\n");
scanf("%f", &newNode->math);
printf("请输入学生英语成绩:\n");
scanf("%f", &newNode->english);
newNode->total = newNode->chinese + newNode->math + newNode->english;
newNode->next = NULL;
// 尾插法添加结点
if (*head == NULL) {
*head = newNode;
} else {
Student *p = *head;
while (p->next != NULL) {
p = p->next;
}
p->next = newNode;
}
}
// 计算并更新学生总分
void calculateTotal(Student **head) {
Student *p = *head;
while (p != NULL) {
p->total = p->chinese + p->math + p->english;
p = p->next;
}
}
// 按总分从大到小排序
void sortByTotal(Student **head) {
Student *p, *q, *tail = NULL;
float temp;
do {
temp = 0;
p = *head;
while (p->next != tail) {
q = p->next;
if (p->total < q->total) {
strcpy(temp, p->name);
strcpy(p->name, q->name);
strcpy(q->name, temp);
strcpy(temp, p->id);
strcpy(p->id, q->id);
strcpy(q->id, temp);
temp = p->chinese;
p->chinese = q->chinese;
q->chinese = temp;
temp = p->math;
p->math = q->math;
q->math = temp;
temp = p->english;
p->english = q->english;
q->english = temp;
temp = p->total;
p->total = q->total;
q->total = temp;
}
p = p->next;
}
tail = p;
} while (temp);
}
// 输出学生信息
void printStudent(Student *node) {
printf("姓名:%s\n", node->name);
printf("学号:%s\n", node->id);
printf("语文成绩:%.2f\n", node->chinese);
printf("数学成绩:%.2f\n", node->math);
printf("英语成绩:%.2f\n", node->english);
printf("总分:%.2f\n", node->total);
}
// 输出所有学生信息
void printAll(Student *head) {
if (head == NULL) {
printf("没有学生信息!\n");
return;
}
printf("学生信息如下:\n");
Student *p = head;
while (p != NULL) {
printStudent(p);
p = p->next;
}
}
// 根据姓名查找学生信息
Student *findStudentByName(Student *head, char *name) {
Student *p = head;
while (p != NULL) {
if (strcmp(p->name, name) == 0) {
return p;
}
p = p->next;
}
return NULL;
}
// 删除学生信息
void deleteStudent(Student **head, char *name) {
if (*head == NULL) {
printf("没有学生信息!\n");
return;
}
Student *p = *head, *prev = NULL;
while (p != NULL) {
if (strcmp(p->name, name) == 0) {
if (prev == NULL) {
*head = p->next;
} else {
prev->next = p->next;
}
free(p);
printf("已删除学生 %s 的信息!\n", name);
return;
}
prev = p;
p = p->next;
}
printf("没有找到姓名为 %s 的学生信息!\n", name);
}
int main() {
Student *head = NULL;
int choice;
char name[MAX_LEN];
while (1) {
printf("\n1. 添加学生信息\n");
printf("2. 计算学生总分\n");
printf("3. 按总分从大到小排序\n");
printf("4. 输出所有学生信息\n");
printf("5. 根据姓名查找学生信息\n");
printf("6. 根据姓名删除学生信息\n");
printf("7. 退出程序\n");
printf("请选择操作:\n");
scanf("%d", &choice);
switch (choice) {
case 1:
addStudent(&head);
break;
case 2:
calculateTotal(&head);
printf("已计算学生总分!\n");
break;
case 3:
sortByTotal(&head);
printf("已按总分从大到小排序!\n");
break;
case 4:
printAll(head);
break;
case 5:
printf("请输入要查找的学生姓名:\n");
scanf("%s", name);
Student *node = findStudentByName(head, name);
if (node == NULL) {
printf("没有找到姓名为 %s 的学生信息!\n", name);
} else {
printStudent(node);
}
break;
case 6:
printf("请输入要删除的学生姓名:\n");
scanf("%s", name);
deleteStudent(&head, name);
break;
case 7:
printf("程序已退出!\n");
return 0;
default:
printf("无效操作,请重新选择!\n");
break;
}
}
}
```
这里定义了一个 `Student` 的结构体,包含学生姓名,学号,语文、数学、英语三门成绩等信息。使用尾插法建立单链表,可以通过添加学生信息实现。每个学生结点也包含 `total` 总分属性,可以通过计算并更新学生总分实现。排序使用了冒泡排序算法,按总分从大到小排序。输出所有学生信息、根据姓名查找学生信息、根据姓名删除学生信息都是对链表的遍历和查找操作。需要注意的是,删除操作是通过传入指向头指针的指针实现的,这样才能修改头指针的指向。
阅读全文