#define _CRT_SECURE_NO_WARNINGS 1
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#define RD_NO (1<<0)
#define RD_NAME (1<<1)
#define RD_SEX (1<<2)
#define RD_SCORE (1<<3)
//描述1个学生的属性
struct STUDENT
{
int no;
char name[64];
char sex;
float score;
};
//创建链表的节点数据结构
struct _node
{
struct STUDENT student;//该节点的数据域
struct _node* pnext; //该节点的指针域
};
void GetInfo(struct STUDENT* p, unsigned char flag);
int Menu(void);
int Link_Add(struct _node* p1);
int ShowAll(struct _node* p1);
int Link_Find(struct _node* p1);
int Link_Change(struct _node* p1);
int Link_Del(struct _node* p1);
//指向头节点的指针变量
struct _node* phead = NULL;
int main()
{
int no;
while (1) {
no = Menu();
switch (no)
{
case 1:Link_Add(phead); break;
case 2:Link_Del(phead); break;
case 3:Link_Change(phead); break;
case 4:Link_Find(phead); break;
case 5:break;
case 6:ShowAll(phead); break;
}
}
}
/*
菜单
参数:无
返回:输入的菜单选项
*/
int Menu(void)
{
int no;
p1:
printf("**学生管理系统**\n");
printf("1 添加学生 \n");
printf("2 删除学生 \n");
printf("3 修改学生 \n");
printf("4 查找学生 \n");
printf("5 成绩排序 \n");
printf("6 打印所有信息 \n");
printf("请输入选项:");
scanf("%d", &no);
if (no >= 1 && no <= 6)
return no;
printf("输入有误,重新输入\n");
goto p1;
}
/*
函数功能:给链表中添加新的新节点
参数:p1 -- 保存链表头的地址
返回值:0 -- 成功
>1 -- 失败
*/
/*
int Link_Add(struct _node *p1)
{
//1.开辟新的节点,使用pnew指向该新的节点
struct _node *pnew = malloc(sizeof(struct _node));
//2.1给节点的数据域赋值
GetInfo(&pnew->student,RD_NO|RD_NAME|RD_SEX|RD_SCORE);
//2.2给节点的指针域赋值
pnew->pnext = NULL;
//3.把新的节点添加到链表中去
//3.1 链表为空
if(phead == NULL){
phead = pnew;
return 0;
}else//尾插法
{
//找到链表尾 -- 根据节点的指针域是否为NULL
while(p1->pnext != NULL){
p1 = p1->pnext;
}
//把新节点添加到链表最后节点的后面(新的节点地址给上一个最后1个节点的指针域)
p1->pnext = pnew;
return 0;
}
}*/
/*
函数功能:给链表中添加新的新节点
参数:p1 -- 保存链表头的地址
返回值:0 -- 成功
>1 -- 失败
*/
/*
int Link_Add(struct _node *p1)
{
//1.开辟新的节点,使用pnew指向该新的节点
struct _node *pnew = malloc(sizeof(struct _node));
//2.1给节点的数据域赋值
GetInfo(&pnew->student,RD_NO|RD_NAME|RD_SEX|RD_SCORE);
//2.2给节点的指针域赋值
pnew->pnext = NULL;
//3.把新的节点添加到链表中去 -- 头插法
//3.1 原来第一个节点的地址给新节点的指针域
pnew->pnext = phead;
phead = pnew;
}*/
/*
函数功能:给链表中添加新的新节点
参数:p1 -- 保存链表头的地址
返回值:0 -- 成功
>1 -- 失败
*/
int Link_Add(struct _node* p1)
{
//1.开辟新的节点,使用pnew指向该新的节点
struct _node* pnew = malloc(sizeof(struct _node));
//2.1给节点的数据域赋值
GetInfo(&pnew->student, RD_NO | RD_NAME | RD_SEX | RD_SCORE);
//2.2给节点的指针域赋值
pnew->pnext = NULL;
//3.把新的节点添加到链表中去 -- 中间插入
//3.1 是否为空链表
if (phead == NULL) {
phead = pnew;
return 0;
}
//3.2 查找位置,进行插入
while (p1 != NULL) {
if (p1->student.no < pnew->student.no)
{
//后续节点为空,直接插入后面
if (p1->pnext == NULL) {
p1->pnext = pnew;
return 0;
}
else if (p1->pnext->student.no > pnew->student.no) {
pnew->pnext = p1->pnext;
p1->pnext = pnew;
return 0;
}
}
else if (p1->student.no>pnew->student.no) {
pnew->pnext = phead;
phead = pnew;
return 0;
}
p1 = p1->pnext;
}
}
/*
函数功能:打印链表中所有节点信息
参数:链表头传递进来
返回值:0 -- 成功
>0 -- 失败
*/
int ShowAll(struct _node* p1)
{
printf("打印所有学生信息操作……\n");
printf("学号\t姓名\t性别\t成绩\n");
while (p1 != NULL) {
printf("%d\t", p1->student.no);
printf("%s\t", p1->student.name);
printf("%c\t", p1->student.sex);
printf("%f\n", p1->student.score);
p1 = p1->pnext;
}
}
/*
从链表中查找某个信息
参数:p1 -- 链表头
返回值:0 -- 成功
>0 -- 失败
*/
int Link_Find(struct _node* p1)
{
struct STUDENT temp = { 0 };//保存要查找的信息
GetInfo(&temp, RD_NO | RD_NAME);
//循环比较学号
while (p1 != NULL)
{
if (p1->student.no == temp.no) {
if (strcmp(p1->student.name, temp.name) == 0) {
printf("找到该学生,信息如下:\n");
printf("%d\t", p1->student.no);
printf("%s\t", p1->student.name);
printf("%c\t", p1->student.sex);
printf("%f\n", p1->student.score);
return 0;
}
else {
printf("学号正确,姓名不对\n");
}
}
p1 = p1->pnext;
}
printf("查无此人\n");
return 1;
}
/*
修改链表节点的内容
参数:p1 -- 指向链表头
返回值:0 -- 正确
>0 -- 错误
*/
int Link_Change(struct _node* p1)
{
struct STUDENT temp = { 0 };
GetInfo(&temp, RD_NO | RD_NAME);
while (p1 != NULL) {
if (p1->student.no == temp.no) {
if (strcmp(p1->student.name, temp.name) == 0) {
GetInfo(&temp, RD_NO | RD_NAME | RD_SEX | RD_SCORE);
p1->student = temp;
return 0;
}
}
p1 = p1->pnext;
}
printf("查无此人\n");
return 1;
}
/*
删除链表中某个节点
p1 -- 链表头
返回值: 0 -- 成功
>0 -- 失败
1 -- 链表为空
2 -- 链表中查询不到
*/
int Link_Del(struct _node* p1)
{
if (p1 == NULL) {//空链表
return 1;//链表为空
}
struct STUDENT temp = { 0 };
GetInfo(&temp, RD_NO);
struct _node* pdel = NULL;//保存要删除节点的首地址
//1.判断是否是第一个节点
if (p1->student.no == temp.no) {
pdel = p1;
phead = pdel->pnext;//要删除的节点的指针域给链表头指针
free(pdel);
return 0;
}//第2个节点开始
while (p1->pnext != NULL) {//代表下一个节点空间是否存在
if (p1->pnext->student.no == temp.no) {
pdel = p1->pnext;
p1->pnext = pdel->pnext;
free(pdel);
return 0;
}
p1 = p1->pnext;
}
return 2;
}
/*
flag = 相应的选项是否允许输入
[0]位 -- no_flag 1--允许输入 0 -- 不允许输入
[1]位 -- name_flag 1--允许输入 0 -- 不允许输入
[2]位 -- sex_flag 1--允许输入 0 -- 不允许输入
[3]位 -- score_flag 1--允许输入 0 -- 不允许输入
*/
void GetInfo(struct STUDENT* p, unsigned char flag)
{
if (flag & (1 << 0)) {
printf("请输入学号:");
scanf("%d", &p->no);
}
if (flag & (1 << 1)) {
printf("请输入姓名:");
scanf("%s", p->name);
}
if (flag & (1 << 2)) {
printf("请输入性别:");
getchar();
scanf("%c", &p->sex);
}
if (flag & (1 << 3)) {
printf("请输入成绩:");
scanf("%f", &p->score);
}
}
学生管理系统单链表
精选 原创
©著作权归作者所有:来自51CTO博客作者GUO_战军的原创作品,请联系作者获取转载授权,否则将追究法律责任
上一篇:C-学生管理系统动态版
下一篇:学生管理系统双链表
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
【java】学生管理系统
简单实现学生管理系统
学生管理系统 增删改查 登录注册 -
2.单链表逆置
单链表逆置
单链表逆置 List -
简单的单链表排序 —— 学生管理程序
昨晚,正在准备考研的小C叫我帮他调试一下他的代码,看了他发的CPP,居然只有一个main函数,一大堆a1,b1,c1等变量,确实改得蛋疼,不如自己重写一个....
file class insert null 数据库 -
【学生管理系统】学生管理(重点)
查询所有、环境搭建、添加学生、修改学生、分页
java spring boot spring mysql ci