按照以下问题写出算法设计思路以及C语言代码:现有A、B两个班级的学生,学生的信息包括学号、姓名、成绩,将这两个班级的学生按照学号顺序分别保存在两个单链表中(学号从1开始编号)。 期末时经过转专业考试后,A班从i号开始有len个学生转专业考试通过,转到B班级,转到B班级后,将这len个学生安排在B班的j号学生之前。 请编写程序,先输入A、B班级的学生信息,再输入i,len和j的值,最后输出转专业后,A、B班的学生信息(按照顺序输出)。
时间: 2024-03-25 12:40:54 浏览: 100
算法设计思路:
1. 定义一个结构体类型 `Student`,包括学号、姓名、成绩这三个成员。
2. 定义一个单链表类型 `LinkedList`,包括头指针、尾指针和链表长度这三个成员。头指针和尾指针分别指向链表的头结点和尾结点,链表长度表示链表中元素的个数。
3. 定义一个函数 `createLinkedList`,用于创建一个空的单链表。
4. 定义一个函数 `addStudent`,用于向单链表中添加一个学生。
5. 定义一个函数 `printLinkedList`,用于按顺序输出单链表中的所有学生。
6. 定义一个函数 `transferStudents`,用于将 A 班的学生转到 B 班的指定位置。
C语言代码如下:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义学生结构体
typedef struct student {
int id; // 学号
char name[20]; // 姓名
float score; // 成绩
} Student;
// 定义单链表结构体
typedef struct node {
Student data; // 数据域
struct node *next; // 指针域
} Node, *LinkedList;
// 创建一个空的单链表
LinkedList createLinkedList() {
LinkedList head = (LinkedList) malloc(sizeof(Node)); // 创建头结点
head->next = NULL; // 初始为空链表
return head;
}
// 向单链表中添加一个学生
void addStudent(LinkedList list, Student s) {
Node *p = list; // 从头结点开始遍历
while (p->next != NULL && p->next->data.id < s.id) {
p = p->next; // 找到插入位置的前一个结点
}
Node *node = (Node *) malloc(sizeof(Node)); // 创建新结点
node->data = s;
node->next = p->next; // 插入结点
p->next = node;
list->data = list->data + 1; // 链表长度加一
}
// 按顺序输出单链表中的所有学生
void printLinkedList(LinkedList list) {
Node *p = list->next; // 从第一个结点开始遍历
while (p != NULL) {
printf("%d %s %.2f\n", p->data.id, p->data.name, p->data.score);
p = p->next;
}
}
// 将 A 班的学生转到 B 班的指定位置
void transferStudents(LinkedList a, LinkedList b, int i, int len, int j) {
Node *p = a; // 从头结点开始遍历
while (p->next != NULL && p->next->data.id < i) {
p = p->next; // 找到转专业开始位置的前一个结点
}
Node *q = p->next; // 转专业开始位置的第一个结点
int count = 0; // 计数器
while (q != NULL && count < len) {
Node *node = q; // 保存当前结点
q = q->next; // 指向下一个结点
addStudent(b, node->data); // 将结点插入 B 班链表
free(node); // 释放 A 班链表中的结点
count++;
}
Node *r = b; // 从头结点开始遍历
int k = 1;
while (r->next != NULL && k < j) {
r = r->next; // 找到插入位置的前一个结点
k++;
}
p->next = q; // 将 A 班链表中转出的结点删除
r->next = p->next; // 将转出的结点插入 B 班链表
}
int main() {
LinkedList a = createLinkedList(); // 创建 A 班链表
LinkedList b = createLinkedList(); // 创建 B 班链表
int n, m, i, len, j;
scanf("%d", &n); // 输入 A 班学生人数
for (int k = 0; k < n; k++) {
Student s;
scanf("%d %s %f", &s.id, s.name, &s.score);
addStudent(a, s); // 将学生添加到 A 班链表
}
scanf("%d", &m); // 输入 B 班学生人数
for (int k = 0; k < m; k++) {
Student s;
scanf("%d %s %f", &s.id, s.name, &s.score);
addStudent(b, s); // 将学生添加到 B 班链表
}
scanf("%d %d %d", &i, &len, &j); // 输入转专业的起始位置、转出的学生人数和转入的位置
transferStudents(a, b, i, len, j); // 将 A 班的学生转到 B 班的指定位置
printf("A班学生信息:\n");
printLinkedList(a); // 输出 A 班学生信息
printf("B班学生信息:\n");
printLinkedList(b); // 输出 B 班学生信息
return 0;
}
```
注意:在添加学生和转专业时,需要保证链表中的结点按照学号从小到大排列。
阅读全文