题目要求:
创建一个 单向链表 来记录学生信息,人数3–5人;链表结点为结构变量,结构的要求如下:
struct stu_info
{
char stu_num[10]; //学号
char stu_name[8]; //姓名
char stu_sex[2]; //性别
int stu_score //成绩
struct stu_info *next;
};
程序设计要求:
(1)插入新的学生信息(插入节点的位置可任意指定)
(2)删除指定的学生信息
(3)根据学号查询并显示查询到的学生信息
(4)以上三项任务分别自定义函数实现,执行后显示执行结果
(5)程序运行后要求可以循环执行前三项操作,直到选择退出时结束程序
完整代码:
#include<bits/stdc++.h>
#include <cstdlib>
struct stu_info {
char stu_num[10]; // 学号
char stu_name[8]; // 姓名
char stu_sex[2]; // 性别
int stu_score; // 成绩
struct stu_info *next; // 指向下一个结点的指针
};
// 插入新的学生信息
void insert_node(struct stu_info **head, char *stu_num, char *stu_name, char *stu_sex, int stu_score, int pos) {
// 申请新结点
struct stu_info *new_node = new stu_info;
// 将新结点的信息赋值
strcpy(new_node->stu_num, stu_num);
strcpy(new_node->stu_name, stu_name);
strcpy(new_node->stu_sex, stu_sex);
new_node->stu_score = stu_score;
// 如果要插入的位置是第一个,则直接将新结点插入到链表头
if (pos == 1) {
new_node->next = *head;
*head = new_node;
return;
}
// 否则,在链表中找到要插入的位置
struct stu_info *p = *head;
int i;
for (i = 1; i < pos - 1 && p != NULL; i++) {
p = p->next;
}
// 如果找到了要插入的位置,则将新结点插入到该位置
if (p != NULL) {
new_node->next = p->next;
p->next = new_node;
}
}
// 删除指定的学生信息
void delete_node(struct stu_info **head, char *stu_num) {
// 先找到要删除的结点的前一个结点
struct stu_info *prev = *head;
while (prev->next != NULL && strcmp(prev->next->stu_num, stu_num) != 0) {
prev = prev->next;
}
// 如果找到了要删除的结点,则将前一个结点的 next 指针指向要删除的结点的下一个结点
if (prev->next != NULL) {
struct stu_info *node_to_delete = prev->next;
prev->next = node_to_delete->next;
free(node_to_delete);
}
}
// 根据学号查询并显示查询到的学生信息
void find_node(struct stu_info *head, char *stu_num) {
struct stu_info *node = head;
while (node != NULL) {
if (strcmp(node->stu_num, stu_num) == 0) {
// 找到了学号匹配的结点,输出其信息
printf("学号: %s\n", node->stu_num);
printf("姓名: %s\n", node->stu_name);
printf("性别: %s\n", node->stu_sex);
printf("成绩: %d\n", node->stu_score);
return;
}
node = node->next;
}
// 如果没有找到学号匹配的结点,则输出提示
printf("未找到学号为 %s 的学生信息\n", stu_num);
}
int main() {
// 初始化链表
struct stu_info *head = NULL;
// 循环执行操作
int op;
do {
printf("\n1. 插入学生信息\n");
printf("2. 删除学生信息\n");
printf("3. 查询学生信息\n");
printf("4. 退出\n");
printf("请选择要执行的操作: ");
scanf("%d", &op);
switch (op) {
case 1: {
// 插入学生信息
char stu_num[10];
int pos;
char stu_name[8];
char stu_sex[2];
int stu_score;
printf("请输入要插入的学号: ");
scanf("%s", stu_num);
printf("请输入要插入的姓名: ");
scanf("%s", stu_name);
printf("请输入要插入的性别: ");
scanf("%s", stu_sex);
printf("请输入要插入的成绩: ");
scanf("%d", &stu_score);
printf("请输入要插入的位置(1-based): ");
scanf("%d", &pos);
insert_node(&head, stu_num, stu_name, stu_sex, stu_score, pos);
break;
}
case 2: {
// 删除学生信息
char stu_num[10];
printf("请输入要删除的学号: ");
scanf("%s", stu_num);
delete_node(&head, stu_num);
break;
}
case 3: {
// 查询学生信息
char stu_num[10];
printf("请输入要查询的学号: ");
scanf("%s", stu_num);
find_node(head, stu_num);
break;
}
case 4: {
// 退出程序
break;
}
default: {
printf("输入错误,请重新输入\n");
break;
}
}
} while (op != 4);
return 0;
}
运行截图:
整体简介
段代码实现了一个带头结点的单链表,其中定义了四个函数:
insert_node 函数:在单链表的指定位置插入一个新的学生信息结点。
delete_node 函数:删除单链表中指定学号的学生信息结点。
find_node 函数:根据学号查询并显示查询到的学生信息。
display_list 函数:显示单链表中所有学生信息。
结构体 stu_info 定义了学生信息结点所包含的信息,包括学号、姓名、性别、成绩以及指向下一个结点的指针。
使用时,你需要先创建一个带头结点的单链表,然后调用上述四个函数来插入、删除和查询学生信息,或者调用 display_list 函数来显示整个单链表。
例如,如果你想要在单链表的第二个位置插入一个新的学生信息结点,可以这样调用 insert_node 函数:
insert_node(&head, “123456”, “John”, “M”, 85, 2);
这里,head 是指向单链表头结点的指针,后面的参数分别是学号、姓名、性别、成绩和插入位置。
函数介绍:
insert_node
insert_node 函数是用来在单链表的指定位置插入一个新的学生信息结点的。它有两个参数:
head:指向单链表头结点的指针。
pos:插入位置。
除此之外,还有其他四个参数,分别是学号、姓名、性别和成绩。
使用时,你可以这样调用 insert_node 函数:
insert_node(&head, “123456”, “John”, “M”, 85, 2);
这里,head 是指向单链表头结点的指针,2 是插入位置,后面的参数分别是学号、姓名、性别和成绩。
代码:
// 插入新的学生信息
void insert_node(struct stu_info **head, char *stu_num, char *stu_name, char *stu_sex, int stu_score, int pos) {
// 申请新结点
struct stu_info *new_node = (struct stu_info*)malloc(sizeof(struct stu_info));
// 将新结点的信息赋值
strcpy(new_node->stu_num, stu_num);
strcpy(new_node->stu_name, stu_name);
strcpy(new_node->stu_sex, stu_sex);
new_node->stu_score = stu_score;
// 如果要插入的位置是第一个,则直接将新结点插入到链表头
if (pos == 1) {
new_node->next = *head;
*head = new_node;
return;
}
// 否则,在链表中找到要插入的位置
struct stu_info *p = *head;
int i;
for (i = 1; i < pos - 1 && p != NULL; i++) {
p = p->next;
}
// 如果找到了要插入的位置,则将新结点插入到该位置
if (p != NULL) {
new_node->next = p->next;
p->next = new_node;
}
}
delete_node
这个函数有两个参数:
head:指向单链表头结点的指针,用于修改链表结构。
stu_num:要删除的学生的学号。
在函数内部,首先会找到要删除的结点的前一个结点。如果找到了要删除的结点,则将前一个结点的 next 指针指向要删除的结点的下一个结点,最后将要删除的结点释放掉。
使用时,你可以这样调用 delete_node 函数:
delete_node(&head, “123456”);
这里,head 是指向单链表头结点的指针,“123456” 是要删除的学生的学号。
代码:
// 删除指定的学生信息
void delete_node(struct stu_info **head, char *stu_num) {
// 先找到要删除的结点的前一个结点
struct stu_info *prev = *head;
while (prev->next != NULL && strcmp(prev->next->stu_num, stu_num) != 0) {
prev = prev->next;
}
// 如果找到了要删除的结点,则将前一个结点的 next 指针指向要删除的结点的下一个结点
if (prev->next != NULL) {
struct stu_info *node_to_delete = prev->next;
prev->next = node_to_delete->next;
free(node_to_delete);
}
}
find_node
这个函数有两个参数:
head
:指向单链表头结点的指针,用于遍历链表。stu_num
:要查询的学生的学号。
在函数内部,首先会从链表头开始遍历,每次遍历时比较当前结点的学号与要查询的学号是否相同。如果相同,则显示该结点的信息,然后结束遍历。
使用时,你可以这样调用 find_node
函数:
find_node(head, “123456”);
这里,head
是指向单链表头结点的指针,"123456"
是要查询的学生的学号。
代码:
// 根据学号查询并显示查询到的学生信息
void find_node(struct stu_info *head, char *stu_num) {
struct stu_info *node = head;
while (node != NULL) {
if (strcmp(node->stu_num, stu_num) == 0) {
// 找到了学号匹配的结点,输出其信息
printf("学号: %s\n", node->stu_num);
printf("姓名: %s\n", node->stu_name);
printf("性别: %s\n", node->stu_sex);
printf("成绩: %d\n", node->stu_score);
return;
}
node = node->next;
}
// 如果没有找到学号匹配的结点,则输出提示
printf("未找到学号为 %s 的学生信息\n", stu_num);
}