给出n个学生的考试成绩表,每条记录由学号、姓名和分数和名次组成,设计算法完成下列操作: (1)设计一个显示对学生信息操作的菜单函数如下所示: ************************* 1、录入学生基本信息 2、直接插入排序 3、冒泡排序 4、快速排序 5、简单选择排序 6、堆排序 7、2-路归并排序 8、输出学生信息 0、退出 ************************* (2)算法设计要求:按分数从高到低的顺序进行排序,分数相同的为同一名次。输入的学生信息存入文件中,每选择一种排序方法,必须从文件中取出数据。用c语言数据结构完成并且给我一个总的示例
时间: 2025-06-20 13:56:35 浏览: 9
### 学生信息管理系统设计与实现(C语言)
以下是基于用户需求的学生信息管理系统的完整设计方案和实现方法。系统将包含菜单驱动界面、多种排序算法以及文件操作支持。
#### 1. 系统概述
学生信息管理系统需要支持以下功能:
- **数据存储**:将学生信息保存到文件中,每次运行程序时重新读取文件中的数据[^1]。
- **排序功能**:使用多种排序算法对学生分数进行从高到低排序,分数相同的为同一名次。
- **菜单驱动界面**:提供友好的用户交互界面,允许用户选择不同的排序算法或退出系统。
#### 2. 数据结构设计
每个学生的信息可以表示为一个结构体,包含以下字段:
- 姓名 (`name`)
- 分数 (`score`)
- 名次 (`rank`)
在排序时,需要计算名次字段,确保分数相同的学生成绩排名一致。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STUDENTS 100
typedef struct {
int id;
char name[50];
int score;
int rank;
} Student;
Student students[MAX_STUDENTS];
int student_count = 0;
```
#### 3. 排序算法实现
##### 3.1 直接插入排序
直接插入排序的核心思想是将新元素插入到已排序序列的适当位置[^2]。
```c
void insertion_sort(Student arr[], int n) {
for (int i = 1; i < n; i++) {
Student key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j].score < key.score) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
```
##### 3.2 冒泡排序
冒泡排序通过多次比较相邻元素并交换它们的位置来完成排序[^2]。
```c
void bubble_sort(Student arr[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j].score < arr[j + 1].score) {
Student temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
```
##### 3.3 快速排序
快速排序是一种分治算法,通过选择基准值将数组分为两部分并递归排序。
```c
void quick_sort(Student arr[], int left, int right) {
if (left >= right) return;
int pivot = arr[left + (right - left) / 2].score;
int i = left, j = right;
while (i <= j) {
while (arr[i].score > pivot) i++;
while (arr[j].score < pivot) j--;
if (i <= j) {
Student temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
}
quick_sort(arr, left, j);
quick_sort(arr, i, right);
}
```
##### 3.4 简单选择排序
简单选择排序通过找到未排序部分的最大值并将其放置在正确位置完成排序。
```c
void selection_sort(Student arr[], int n) {
for (int i = 0; i < n - 1; i++) {
int max_idx = i;
for (int j = i + 1; j < n; j++) {
if (arr[max_idx].score < arr[j].score) {
max_idx = j;
}
}
if (max_idx != i) {
Student temp = arr[i];
arr[i] = arr[max_idx];
arr[max_idx] = temp;
}
}
}
```
##### 3.5 堆排序
堆排序利用最大堆的性质,逐步将最大值移至数组末尾完成排序。
```c
void heapify(Student arr[], int n, int i) {
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && arr[left].score > arr[largest].score) largest = left;
if (right < n && arr[right].score > arr[largest].score) largest = right;
if (largest != i) {
Student temp = arr[i];
arr[i] = arr[largest];
arr[largest] = temp;
heapify(arr, n, largest);
}
}
void heap_sort(Student arr[], int n) {
for (int i = n / 2 - 1; i >= 0; i--) heapify(arr, n, i);
for (int i = n - 1; i > 0; i--) {
Student temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
heapify(arr, i, 0);
}
}
```
##### 3.6 2-路归并排序
归并排序通过递归地将数组分为两部分并合并它们完成排序[^2]。
```c
void merge(Student arr[], int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;
Student L[n1], R[n2];
for (int i = 0; i < n1; i++) L[i] = arr[left + i];
for (int j = 0; j < n2; j++) R[j] = arr[mid + 1 + j];
int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (L[i].score >= R[j].score) {
arr[k++] = L[i++];
} else {
arr[k++] = R[j++];
}
}
while (i < n1) arr[k++] = L[i++];
while (j < n2) arr[k++] = R[j++];
}
void merge_sort(Student arr[], int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2;
merge_sort(arr, left, mid);
merge_sort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
}
```
#### 4. 名次计算
在排序完成后,需要计算学生的名次。如果两个学生的分数相同,则他们的名次相同。
```c
void assign_ranks(Student arr[], int n) {
int rank = 1;
int prev_score = -1;
for (int i = 0; i < n; i++) {
if (i == 0 || arr[i].score != prev_score) {
rank = i + 1;
}
arr[i].rank = rank;
prev_score = arr[i].score;
}
}
```
#### 5. 文件操作
文件操作包括读取和写入学生数据。
```c
void save_students_to_file(const char *filename) {
FILE *file = fopen(filename, "w");
if (file == NULL) {
printf("无法打开文件 %s\n", filename);
return;
}
for (int i = 0; i < student_count; i++) {
fprintf(file, "%d %s %d %d\n", students[i].id, students[i].name, students[i].score, students[i].rank);
}
fclose(file);
}
void load_students_from_file(const char *filename) {
FILE *file = fopen(filename, "r");
if (file == NULL) {
printf("无法打开文件 %s\n", filename);
return;
}
student_count = 0;
while (fscanf(file, "%d %s %d %d", &students[student_count].id, students[student_count].name,
&students[student_count].score, &students[student_count].rank) != EOF) {
student_count++;
}
fclose(file);
}
```
#### 6. 菜单驱动界面
最后,设计一个简单的菜单驱动界面供用户选择不同的排序算法。
```c
void display_menu() {
printf("\n学生信息管理系统\n");
printf("1. 录入学生基本信息\n");
printf("2. 直接插入排序\n");
printf("3. 冒泡排序\n");
printf("4. 快速排序\n");
printf("5. 简单选择排序\n");
printf("6. 堆排序\n");
printf("7. 2-路归并排序\n");
printf("8. 输出学生信息\n");
printf("0. 退出\n");
}
void main_menu() {
const char *filename = "students.txt";
load_students_from_file(filename);
while (1) {
display_menu();
int choice;
printf("请选择操作: ");
scanf("%d", &choice);
switch (choice) {
case 1:
// 录入学生基本信息
break;
case 2:
insertion_sort(students, student_count);
assign_ranks(students, student_count);
break;
case 3:
bubble_sort(students, student_count);
assign_ranks(students, student_count);
break;
case 4:
quick_sort(students, 0, student_count - 1);
assign_ranks(students, student_count);
break;
case 5:
selection_sort(students, student_count);
assign_ranks(students, student_count);
break;
case 6:
heap_sort(students, student_count);
assign_ranks(students, student_count);
break;
case 7:
merge_sort(students, 0, student_count - 1);
assign_ranks(students, student_count);
break;
case 8:
for (int i = 0; i < student_count; i++) {
printf("ID: %d, Name: %s, Score: %d, Rank: %d\n", students[i].id, students[i].name, students[i].score, students[i].rank);
}
break;
case 0:
save_students_to_file(filename);
exit(0);
default:
printf("无效的选择,请重试!\n");
}
}
}
int main() {
main_menu();
return 0;
}
```
####
阅读全文