建立一个大小为3(可扩展为n)个学生成绩信息包括(学号、姓名、成绩)的单向链表,学生数据按学号由小到大顺序排列,要求实现删除操作。输入任意指定学号,从单向链表中删除该学生信息。
二、实验要求:
1、理解并掌握该问题的实现方法。
2、代码书写格式规范,测试结果符合期望结果。
3、通过动态内存产生结点、调用函数完成链表建立、链表遍历、指定结点删除操作,画流程图和实现代码。
5、测试用例如下:
输入:1 张三 80
2 李四 95
3 王五 70
删除:2
输出:1 张三 80
3 王五 70
【流程图】
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 学生数据结构体
typedef struct Student {
int id; // 学号
char name[20]; // 姓名
float score; // 成绩
struct Student* next; // 下一节点指针
} Student;
// 动态生成学生数据节点
Student* createStudent(int id, char* name, float score) {
Student* newStudent = (Student*)malloc(sizeof(Student));
newStudent->id = id;
strcpy(newStudent->name, name);
newStudent->score = score;
newStudent->next = NULL;
return newStudent;
}
// 在单向链表中插入新节点
void insertNode(Student** head, Student* newNode) {
if (*head == NULL) { // 如果链表为空,则直接将新节点作为头节点
*head = newNode;
} else { // 否则按照学号大小插入新节点
Student* p = *head;
Student* q = NULL;
while (p != NULL && p->id < newNode->id) { // 找到第一个比新节点大的节点
q = p;
p = p->next;
}
if (q == NULL) { // 如果新节点的学号最小,则将新节点插入头部
newNode->next = *head;
*head = newNode;
} else { // 否则将新节点插入到合适的位置
q->next = newNode;
newNode->next = p;
}
}
}
// 删除指定学号节点
int deleteNode(Student** head, int id) {
if (*head == NULL) { // 链表为空,无法删除
return 0;
}
if ((*head)->id == id) { // 如果要删除的节点为头节点
Student* p = *head;
*head = (*head)->next; // 将头节点指向下一个节点
free(p); // 删除原头节点
return 1;
}
Student* p = *head;
Student* q = NULL;
while (p != NULL && p->id != id) { // 找到要删除的节点
q = p;
p = p->next;
}
if (p == NULL) { // 如果没有找到要删除的节点
return 0;
}
q->next = p->next; // 将要删除的节点从链表中断开
free(p); // 删除该节点
return 1;
}
// 遍历并输出链表
void printList(Student* head) {
while (head != NULL) { // 遍历整个链表并输出每个节点的信息
printf("%d %s %.2f\n", head->id, head->name, head->score);
head = head->next;
}
}
int main() {
struct Student* head = NULL; // 头指针初始化为空
int choice;
do {
// 输出菜单
printf("请选择要执行的操作:\n");
printf("1. 插入学生信息\n");
printf("2. 删除学生信息\n");
printf("3. 显示所有学生信息\n");
printf("0. 退出\n");
scanf("%d", &choice);
switch (choice) {
case 1: { // 插入学生信息
int id;
char name[100];
float score;
printf("请输入学号、姓名、成绩:");
scanf("%d %s %f", &id, name, &score);
insertNode(&head, createStudent(id, name, score));
break;
}
case 2: { // 删除指定学号的学生信息
int id;
printf("请输入要删除的学号:");
scanf("%d", &id);
if (deleteNode(&head, id)) {
printf("删除成功!\n");
} else {
printf("未找到要删除的节点!\n");
}
break;
}
case 3: // 输出所有学生信息
printf("所有学生信息如下:\n");
printList(head);
break;
case 0: // 退出程序
printf("退出程序\n");
break;
default: // 无效选择
printf("选择无效,请重新输入!\n");
break;
}
} while (choice != 0);
return 0;
}
以下回答参考GPT,并由JoseKe整理完成,希望您能采纳:c
// 链表结构体
typedef struct node{
int id; // 学号
char name[20]; // 姓名
int score; // 成绩
struct node *next; // 下一个节点的指针
}Node;
c
// 创建链表
Node *create(int n) {
if (n <= 0) {
return NULL;
}
// 输入第一个学生的信息
Node *head = (Node*) malloc(sizeof(Node));
head->next = NULL;
printf("请输入第1个学生的信息(学号 姓名 成绩):");
scanf("%d %s %d", &head->id, head->name, &head->score);
// 循环输入每个学生的信息并加入链表(按学号从小到大顺序排列)
for (int i = 1; i < n; i++) {
Node *p = (Node*) malloc(sizeof(Node));
printf("请输入第%d个学生的信息(学号 姓名 成绩):", i+1);
scanf("%d %s %d", &p->id, p->name, &p->score);
Node *q = head, *r = head->next;
while (r && r->id < p->id) {
q = r;
r = r->next;
}
q->next = p;
p->next = r;
}
return head;
}
c
// 删除操作
Node *delete(Node *head, int id) {
Node *p = head->next;
Node *q = head;
while (p && p->id != id) {
q = p;
p = p->next;
}
if (p) {
q->next = p->next;
free(p);
} else {
printf("未找到学号为%d的学生信息
", id);
}
return head;
}
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 链表结构体,包括学生信息和下一个节点的指针
typedef struct node {
int id; // 学号
char name[20]; // 姓名
int score; // 成绩
struct node *next; // 下一个节点的指针
} Node;
// 创建链表
Node *create(int n) {
if (n <= 0) {
return NULL; // 如果学生个数不大于0直接返回空指针
}
Node *head = (Node*) malloc(sizeof(Node)); // 创建头节点
head->next = NULL; // 头节点的指针置为NULL,表示链表为空
printf("请输入第1个学生的信息(学号 姓名 成绩):");
scanf("%d %s %d", &head->id, head->name, &head->score);
for (int i = 1; i < n; i++) { // 循环输入每个学生的信息并加入链表(按学号从小到大顺序排列)
Node *p = (Node*) malloc(sizeof(Node));
printf("请输入第%d个学生的信息(学号 姓名 成绩):", i+1);
scanf("%d %s %d", &p->id, p->name, &p->score);
Node *q = head, *r = head->next;
while (r && r->id < p->id) { // 遍历链表,找到要插入的位置
q = r;
r = r->next;
}
q->next = p; // 在q和r之间插入节点p
p->next = r;
}
return head;
}
// 遍历链表
void display(Node *head) {
if (head->next == NULL) { // 如果链表为空
printf("链表为空
");
return;
}
printf("%d %s %d
", head->id, head->name, head->score); // 先输出头节点信息
Node *p = head->next;
while (p) { // 循环遍历链表,输出每个节点的信息
printf("%d %s %d
", p->id, p->name, p->score);
p = p->next;
}
}
// 删除操作
Node *delete(Node *head, int id) {
Node *p = head->next;
Node *q = head;
while (p && p->id != id) { // 遍历链表找到要删除的节点
q = p;
p = p->next;
}
if (p) { // 如果找到了该节点
q->next = p->next; // 将该节点从链表中摘除并释放内存
free(p);
} else {
printf("未找到学号为%d的学生信息
", id);
}
return head;
}
int main() {
int num, id;
Node *head;
printf("请输入学生个数:");
scanf("%d", &num);
head = create(num); // 创建链表
printf("创建链表成功,链表中所有学生的信息如下:
");
display(head); // 遍历链表
printf("请输入要删除的学生的学号:");
scanf("%d", &id);
head = delete(head, id); // 删除指定学生的信息
printf("删除后,链表中所有学生的信息如下:
");
display(head);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//定义学生信息结构体
struct student {
int num; //学号
char name[20]; //姓名
int score; //成绩
struct student *next; //指向下一个节点的指针
};
//创建链表,并返回头节点指针
struct student* create_list(int n) {
struct student *head, *p, *q;
int i;
head = (struct student *)malloc(sizeof(struct student)); //头节点不存储有效数据
head->next = NULL;
q = head;
for (i = 0; i < n; i++) {
p = (struct student*)malloc(sizeof(struct student)); //创建新节点
printf("请输入第%d个学生的学号、姓名、成绩:", i + 1);
scanf("%d %s %d", &p->num, p->name, &p->score);
//按照学号大小插入到链表中
while (q->next != NULL && q->next->num < p->num) {
q = q->next;
}
p->next = q->next;
q->next = p;
//将q指针重新指向头节点
q = head;
}
return head;
}
//遍历链表并输出每个节点的信息
void traverse_list(struct student *head) {
struct student *p;
p = head->next;
while (p != NULL) {
printf("%d %s %d\n", p->num, p->name, p->score);
p = p->next;
}
}
//删除链表中指定学号的节点
void delete_node(struct student *head, int num) {
struct student *p, *q;
p = head->next;
q = head;
//查找要删除的节点
while (p != NULL && p->num != num) {
q = p;
p = p->next;
}
if (p != NULL) { //找到了要删除的节点
q->next = p->next; //将q的next指向p的下一个节点,跳过p这个节点
free(p); //释放p节点的内存空间
} else {
printf("未找到该学生信息!\n");
}
}
int main() {
struct student* head;
int n, num;
printf("请输入学生的数量:");
scanf("%d", &n);
head = create_list(n);
printf("建立的链表为:\n");
traverse_list(head);
printf("请输入要删除的学生学号:");
scanf("%d", &num);
delete_node(head, num);
printf("删除后的链表为:\n");
traverse_list(head);
return 0;
}
引用chatGPT作答,以下是用C语言编写的简易单链表及其删除操作的实现:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义学生结构体
typedef struct student {
int id; // 学号
char name[20]; // 姓名
int score; // 成绩
struct student *next; // 指向下一个节点的指针
} Student;
// 在单向链表中插入新的学生信息
Student* insert(Student *head, int id, char name[], int score) {
Student *new_student = (Student *)malloc(sizeof(Student));
new_student->id = id;
strcpy(new_student->name, name);
new_student->score = score;
new_student->next = NULL;
// 如果链表为空,则新学生成为头结点
if (head == NULL) {
head = new_student;
return head;
}
// 如果新学生的学号小于头结点的学号,则将新学生成为头结点
if (new_student->id < head->id) {
new_student->next = head;
head = new_student;
return head;
}
// 在单向链表中插入新的学生信息
Student *temp = head;
while (temp->next != NULL && new_student->id > temp->next->id) {
temp = temp->next;
}
new_student->next = temp->next;
temp->next = new_student;
return head;
}
// 在单向链表中删除指定学生信息
Student* delete(Student *head, int id) {
// 如果链表为空,则直接返回
if (head == NULL) {
return head;
}
// 如果要删除的学生是头结点,则将头结点指向下一个节点
if (head->id == id) {
Student *temp = head;
head = head->next;
free(temp);
return head;
}
// 在单向链表中删除指定学生信息
Student *temp = head;
while (temp->next != NULL && temp->next->id != id) {
temp = temp->next;
}
if (temp->next != NULL) {
Student *delete_student = temp->next;
temp->next = temp->next->next;
free(delete_student);
}
return head;
}
// 打印单向链表中所有学生信息
void print(Student *head) {
printf("学号\t姓名\t成绩\n");
Student *temp = head;
while (temp != NULL) {
printf("%d\t%s\t%d\n", temp->id, temp->name, temp->score);
temp = temp->next;
}
}
int main() {
Student *head = NULL;
int id, score, delete_id;
char name[20];
// 读入学生信息
for (int i = 0; i < 3; i++) {
printf("请输入第%d个学生的学号、姓名、成绩(用空格分隔):", i + 1);
scanf("%d %s %d", &id, name, &score);
head = insert(head, id, name, score);
}
// 输出所有学生信息
printf("插入学生后,单向链表中所有学生信息如下:\n");
print(head);
// 删除指定学生信息
printf("请输入要删除的学生的学号:");
scanf("%d", &delete_id);
head = delete(head, delete_id);
// 输出所有学生信息
printf("删除学生后,单向链表中所有学生信息如下:\n");
print(head);
return 0;
}
这个程序将会创建一个大小为3的学生成绩信息单向链表,读入每个学生的学号、姓名和成绩,将学生信息按学号由小到大顺序插入单向链表中。然后,程序将要求用户输入要删除的学生的学号,从单向链表中删除该学生信息,并输出删除后的单向链表中所有学生的信息。
编号 | 选项 |
---|---|
A | 患者编号 |
B | 患者姓名 |
C | 患者编号和患者姓名 |
D | 医生编号和患者编号 |