用c语言选取一个合适的数据结构存储数据,设计一学生成绩表,能对数据进行插入、 删除、统计总分、按总分从大到小排序、查找等。
时间: 2023-12-20 22:07:50 浏览: 92
可以使用链表来存储学生成绩表,每个节点存储一个学生的信息,包括学号、姓名、各科成绩和总分。链表的每个节点都有一个指针指向下一个节点,可以方便地进行插入和删除操作。以下是一个简单的实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NAME_LEN 20 // 姓名长度
#define MAX_SUBJECTS 10 // 最大科目数
// 学生信息结构体
typedef struct student {
int id; // 学号
char name[NAME_LEN]; // 姓名
int scores[MAX_SUBJECTS]; // 各科成绩
int total; // 总分
struct student *next; // 下一个节点指针
} Student;
// 插入节点
void insert_student(Student **head, Student *new_student) {
if (*head == NULL) { // 链表为空,直接插入
*head = new_student;
} else if (new_student->total > (*head)->total) { // 新节点总分最高,插入到链表头部
new_student->next = *head;
*head = new_student;
} else { // 插入到适当位置
Student *prev = *head;
Student *curr = (*head)->next;
while (curr != NULL && new_student->total <= curr->total) {
prev = curr;
curr = curr->next;
}
prev->next = new_student;
new_student->next = curr;
}
}
// 删除节点
void delete_student(Student **head, int id) {
if (*head == NULL) { // 链表为空
return;
}
if ((*head)->id == id) { // 链表头部节点是要删除的节点
Student *temp = *head;
*head = (*head)->next;
free(temp);
return;
}
Student *prev = *head;
Student *curr = (*head)->next;
while (curr != NULL && curr->id != id) {
prev = curr;
curr = curr->next;
}
if (curr != NULL) { // 找到要删除的节点
prev->next = curr->next;
free(curr);
}
}
// 统计总分
int calculate_total(Student *student) {
int total = 0;
for (int i = 0; i < MAX_SUBJECTS; i++) {
total += student->scores[i];
}
student->total = total;
return total;
}
// 按总分从大到小排序
void sort_students(Student **head) {
Student *curr = *head;
*head = NULL;
while (curr != NULL) {
Student *temp = curr;
curr = curr->next;
temp->next = NULL;
insert_student(head, temp); // 插入到新链表的适当位置
}
}
// 查找节点
Student *find_student(Student *head, int id) {
while (head != NULL && head->id != id) {
head = head->next;
}
return head;
}
// 显示学生信息
void display_student(Student *student) {
printf("学号:%d,姓名:%s,各科成绩:", student->id, student->name);
for (int i = 0; i < MAX_SUBJECTS; i++) {
printf("%d ", student->scores[i]);
}
printf(",总分:%d\n", student->total);
}
// 显示学生列表
void display_students(Student *head) {
while (head != NULL) {
display_student(head);
head = head->next;
}
}
int main() {
Student *head = NULL;
while (1) {
printf("请选择操作:\n");
printf("1. 插入学生信息\n");
printf("2. 删除学生信息\n");
printf("3. 统计总分\n");
printf("4. 按总分从大到小排序\n");
printf("5. 查找学生信息\n");
printf("6. 显示学生列表\n");
printf("0. 退出程序\n");
int choice;
scanf("%d", &choice);
switch (choice) {
case 1: { // 插入学生信息
Student *new_student = (Student *)malloc(sizeof(Student));
printf("请输入学号:");
scanf("%d", &(new_student->id));
printf("请输入姓名:");
scanf("%s", new_student->name);
printf("请输入各科成绩(最多%d科):", MAX_SUBJECTS);
for (int i = 0; i < MAX_SUBJECTS; i++) {
if (scanf("%d", &(new_student->scores[i])) != 1) {
new_student->scores[i] = 0;
}
}
calculate_total(new_student); // 计算总分
insert_student(&head, new_student); // 插入节点
printf("学生信息插入成功!\n");
break;
}
case 2: { // 删除学生信息
printf("请输入要删除的学生的学号:");
int id;
scanf("%d", &id);
delete_student(&head, id); // 删除节点
printf("学生信息删除成功!\n");
break;
}
case 3: { // 统计总分
printf("请输入要统计总分的学生的学号:");
int id;
scanf("%d", &id);
Student *student = find_student(head, id); // 查找节点
if (student != NULL) {
int total = calculate_total(student); // 计算总分
printf("学生%d的总分为%d\n", id, total);
} else {
printf("找不到学号为%d的学生!\n", id);
}
break;
}
case 4: { // 按总分从大到小排序
sort_students(&head);
printf("学生信息已按总分从大到小排序!\n");
break;
}
case 5: { // 查找学生信息
printf("请输入要查找的学生的学号:");
int id;
scanf("%d", &id);
Student *student = find_student(head, id); // 查找节点
if (student != NULL) {
display_student(student); // 显示学生信息
} else {
printf("找不到学号为%d的学生!\n", id);
}
break;
}
case 6: { // 显示学生列表
display_students(head);
break;
}
case 0: { // 退出程序
exit(0);
}
default: {
printf("无效的操作!\n");
break;
}
}
}
return 0;
}
```
注意,以上代码只是一个简单的实现,还有很多可以优化的地方,比如可以使用二叉树或哈希表来提高查找的效率。
阅读全文