直接上源码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define RD_ID (1<<0)
#define RD_NAME (1<<1)
#define RD_SCORE (1<<2)
struct student //描述一个学生的属性
{
int ID;
char name[10];
float score;
};
struct node //创建链表的节点数据结构
{
struct student data;
struct node *prior;
struct node *next;
};
void GetInfo(struct student *p,unsigned char flag);
int menu(void); //菜单
int add(struct node *p); //添加
int all_printf(struct node *p); //打印所有学生信息
int delete(struct node *p); //删除
int find(struct node *p); //查找
int change(struct node *p); //修改
int quit(void); //退出
struct node *head = NULL; //指向头节点的指针变量
int main()
{
int num;
while(1)
{
num = menu();
switch(num)
{
case 1:add(head);break;
case 2:delete(head);break;
case 3:change(head);break;
case 4:find(head);break;
case 5:all_printf(head);break;
case 6:quit();return 0;
}
}
}
int menu(void)
{
int num;
printf("\t\t*****欢迎进入学生管理系统*****\n");
printf("\t\t***** 1 添加学生 ***** \n");
printf("\t\t***** 2 删除学生 ***** \n");
printf("\t\t***** 3 修改学生 ***** \n");
printf("\t\t***** 4 查找学生 ***** \n");
printf("\t\t***** 5 打印所有信息 ***** \n");
printf("\t\t***** 6 退出学生系统 ***** \n");
printf("请输入选项:");
scanf("%d",&num);
return num;
}
int add(struct node *p)
{
//创建一个结点,使用new指向这个结点
struct node *new = malloc(sizeof(struct node));
//对该结点数据域进行初始化
GetInfo(&new->data,RD_ID|RD_NAME|RD_SCORE);
//对该结点指针域进行初始化
new->prior = NULL;
new->next = NULL;
//把新的结点插入到链表
if(head == NULL) //如果链表为空
{
head = new;
return 0;
}
while(p != NULL) //链表不为空
{
if(head->data.ID > new->data.ID)
//如果头结点学号大于新结点学号,那就把新结点放在头结点前面
{
head->prior = new;
new->next = head;
head = new;
return 0;
}
if(p->data.ID < new->data.ID)
//如果头结点学号小于新结点学号,那就把新结点放在后面
{
if(p->next == NULL) //插入表尾
{
new->prior = p;
p->next = new;
}
else if(p->next->data.ID > new->data.ID) //中间插入
{
new->prior = p;
new->next = p->next;
p->next->prior = new;
p->next = new;
return 0;
}
}
p = p->next;
}
}
int delete(struct node *p)
{
if(p == NULL)
{
return 1;//链表为空
}
struct student temp = {0};//保存要删除的信息
GetInfo(&temp,RD_ID); //输入要删除的学号
struct node *del = NULL; //保存要删除结点的地址
while(p != NULL)
{
if(p->data.ID == temp.ID)
del = p; //保存要删除结点的地址
{
if(del->prior == NULL && del->next == NULL)//只有一个结点
{
head = NULL;
free(del);
return 0;
}
if(del->prior != NULL) //中间结点
del->prior->next = del->next;
else //删除结点为第一个结点
{
del->next->prior = NULL;
head = del->next; //头指针指向del下一个结点
}
if(del->next != NULL) //如果删除结点后面不为空
del->next->prior = del->prior; //把删除结点后面结点的地址给del前面
else //del指向最后一个结点
{
del->prior->next = NULL; //把del指向的前一个结点的next赋为空
}
free(del);
printf("删除成功\n");
return 0;
}
p = p->next;
}
printf("查无此人\n");
}
int find(struct node *p)
{
struct student temp = {0};
GetInfo(&temp,RD_ID);
while(p != NULL)
{
if(p->data.ID == temp.ID)
{
printf("此人信息如下\n");
printf("%d\t",p->data.ID);
printf("%s\t",p->data.name);
printf("%f\n",p->data.score);
return 0;
}
p = p->next;
}
printf("未找到此人\n");
return 1;
}
int change(struct node *p)
{
struct student temp = {0};
GetInfo(&temp,RD_ID);
while(p != NULL)
{
if(p->data.ID == temp.ID)
{
GetInfo(&temp,RD_ID|RD_NAME|RD_SCORE);
p->data = temp;
printf("修改成功\n");
return 0;
}
p = p->next;
}
printf("查无此人\n");
}
int quit(void)
{
return 0;
}
int all_printf(struct node *p) //打印所有学生信息
{
printf("打印所有学生信息操作……\n");
printf("学号\t姓名\t成绩\n");
while(p != NULL)
{
printf("%d\t",p->data.ID);
printf("%s\t",p->data.name);
printf("%f\n",p->data.score);
p = p->next;
}
}
/*
flag = 相应的选项是否允许输入
[0]位 -- no_flag 1--允许输入 0 -- 不允许输入
[1]位 -- name_flag 1--允许输入 0 -- 不允许输入
[2]位 -- sex_flag 1--允许输入 0 -- 不允许输入
*/
void GetInfo(struct student *p,unsigned char flag)
{
if(flag & (1<<0))
{
printf("请输入学号:");
scanf("%d",&p->ID);
}
if(flag & (1<<1))
{
printf("请输入姓名:");
scanf("%s",p->name);
}
if(flag &(1<<2))
{
printf("请输入成绩:");
scanf("%f",&p->score);
}
}