#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <assert.h>
//案例需求:使用双向 带头 循环链表实现学生信息系统的增删改查
//定义学生信息结构体类型
typedef struct student {
int id;//学号
char uname[20];//姓名
char sex[5];//性别
double score;//成绩
}st;
typedef struct student_dlink {
struct student_dlink* pre;//指向上一个节点指针
st s;//存储节点
struct student_dlink* next;//指向下一个节点指针
}STD;
void print_menu(void);
STD* create_node();
STD* init_List();
void head_insert(STD* SDList);
void print_list(STD* SDList);
STD* find_list(STD* SDList, int id);
void delete_list(STD* SDList, int id);
void change_list(STD* SDList, int id);
void destory(STD** SDList);
int main() {
print_menu();
int order = 0;
STD* SDList = NULL;//学生链表的哨兵位
int id = 0;//学生的id
while (1) {
printf("请输入您的操作指令:");
scanf("%d", &order);
switch (order) {
case 1:
//初始化 一个空的双链表(只有一个哨兵位)
SDList = init_List();
break;
case 2:
//打印
print_list(SDList);
break;
case 3:
//追加
head_insert(SDList);
break;
case 4:
//删除 根据id删除
printf("请输入要删除学生的id:");
scanf("%d", &id);
delete_list(SDList, id);
break;
case 5:
//修改
printf("请输入要修改学生的id:");
scanf("%d", &id);
change_list(SDList, id);
break;
case 6:
//查询
//思路:根据id查询 查到了返回该学生的地址,根据地址输出信息;查不到返回NULL
printf("请输入要查询学生的id:");
scanf("%d", &id);
STD* ptr = find_list(SDList, id);
if (!ptr) {
printf("查无此人\n");
}
else {
printf("%d %s %s %.2lf\n", ptr->s.id, ptr->s.uname, ptr->s.sex, ptr->s.score);
}
break;
case 7:
//销毁
destory(&SDList);
break;
case 8:
//退出
return;
default:
printf("指令输入有误,请重新输入");
//break;
}
}
return 0;
}
//打印菜单
void print_menu(void) {
printf(" 欢迎使用学生成绩管理系统\n");
printf("* =============================== *\n");
printf("操作指令说明:\n");
printf("* 1.初始化 *\n");
printf("* 2.打印 *\n");
printf("* 3.追加 *\n");
printf("* 4.删除 *\n");
printf("* 5.修改 *\n");
printf("* 6.查询 *\n");
printf("* 7.销毁 *\n");
printf("* 8.退出系统 *\n");
printf("* =============================== *\n");
}
//辅助函数,创建新节点
STD* create_node() {
STD* newnode = (STD*)malloc(sizeof(STD));
if (newnode == NULL) {
printf("内存申请失败,无法创建新节点\n");
return NULL;
}
//内存清0
memset(newnode, 0, sizeof(STD));
return newnode;
}
//初始化
STD* init_List() {
//创建新节点
STD* newnode = create_node();
//给新节点赋值
newnode->pre = newnode;
newnode->next = newnode;
printf("初始化成功\n");
return newnode;
}
//追加
void head_insert(STD* SDList) {
st stu;//定义结构体变量 存储学生信息
printf("请输入追加学生的学号 姓名 性别 成绩:");
scanf("%d %s %s %lf", &stu.id, stu.uname, stu.sex, &stu.score);
//printf("%d %s %s %.2lf",s.id, s.uname, s.sex, s. score)
//创建新节点
STD* newnode = create_node();
newnode->s = stu;
//考虑到追加前链表是否存在元素节点
newnode->pre = SDList->pre;
SDList->pre->next = newnode;
newnode->next = SDList;
SDList->pre = newnode;
printf("追加成功\n");
}
//打印
void print_list(STD* SDList) {
assert(SDList);
if (SDList->next == SDList) {
printf("空表无法打印\n");
return;
}
//遍历
STD* temp = SDList->next;
printf("学号 姓名 性别 成绩\n");
while (temp != SDList) {
printf("%d %s %s %.2lf\n", temp->s.id, temp->s.uname, temp->s.sex, temp->s.score);
temp = temp->next;
}
}
//查询
STD* find_list(STD* SDList, int id) {
assert(SDList);
STD* temp = SDList->next;
while (temp != SDList) {
if (temp->s.id == id) {
return temp;
}
temp = temp->next;
}
return NULL;
}
//删除
void delete_list(STD* SDList, int id) {
//查询是否有此人
STD* ptr = find_list(SDList, id);
if (!ptr) {
printf("您要删除的学生不存在\n");
return;
}
ptr->pre->next = ptr->next;
ptr->next->pre = ptr->pre;
free(ptr);
printf("删除成功\n");
}
//修改
void change_list(STD* SDList, int id) {
//查询是否有此人
STD* ptr = find_list(SDList, id);
if (!ptr) {
printf("您要修改的学生不存在\n");
return;
}
//修改
printf("请输入修改后的新学生的学号 姓名 性别 成绩:\n");
scanf("%d %s %s %lf", &(ptr->s.id), &(ptr->s.uname), &(ptr->s.sex), &(ptr->s.score));
printf("修改成功\n");
}
//销毁
void destory(STD** SDList) {
assert(SDList);
//遍历后,一个一个释放
STD* temp = (*SDList)->next;//保存第一个元素节点
while (temp != *SDList) {
STD* ptr = temp->next;//先保存下一个元素
free(temp);
temp = ptr;
}
free(*SDList);//释放哨兵位
*SDList = NULL;
printf("销毁成功\n");
}