双循环链表(学生管理系统)
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
typedef struct student//定义数据结构体
{
int number;
char name[20];
char sex[4];
float suiji;
float English;
float tulun;
float average;
}Stu;
typedef struct node
{
struct node *prior;//节点前向指针
Stu data;//节点数据
struct node *next;//节点后向指针
}Node;
HANDLE lqc;
int count=0;//定义记录学生个数的全局变量
void gotoxy(int x,int y)//使光标跳到指定位置
{
lqc=GetStdHandle(STD_OUTPUT_HANDLE);
COORD stay;
stay.X=x;
stay.Y=y;
SetConsoleCursorPosition(lqc,stay);
}
int show()//登录界面显示
{
char zhanghao[15];
char password[15];
while(1)
{
system("color 1c");
printf("\n\n\n\n\n\n\n\n\t\t\t\t 学生登录\n");
printf("\t\t\t\t\t\t\t \n");
printf("\t\t\t 账号:________________");
printf("\t\t\t\t\t\t\t \n");
printf("\t\t\t 密码:________________");
gotoxy(62,23);
printf("by—lqc");
gotoxy(31,10);//光标跳到指定位置
scanf("%s",zhanghao);
gotoxy(31,12);
scanf("%s",password);
if(strcmp("12345678",zhanghao)!=0||strcmp("666",password)!=0)
{
printf("\n\t\t\t账号或密码错误!5秒后请重新输入......\n");
Sleep(5000);//延时5秒
system("cls");
}
else
break;
}
printf("\t\t\t\t\t\t\t \n\n");
printf("\t\t\t登陆成功!3秒后自动转入主页面......\n");
Sleep(3000);//延时3秒
system("cls");
return 0;
}
Node *judge(Node *s,Node *head)//判断创建的学号是否和已存在的学号相同
{
Node *p;
int n,i;
n=s->data.number;//暂存想创建的学号
p=head->next;//使p指向头结点后第一个节点
for(i=0;i<count;i++)
{
if(p->data.number!=n)//当创建的学号和已存在的学号不相同时
{
p=p->next;//使p指向下一节点
if(i==count-1)
return NULL;//和已存在的学号不同返回NULL
}
else
return p;//和已存在的学号相同返回p
}
}
Node *find_stu(Node *head)//查看学生数据
{
Node *p;
int num;
if(head==NULL)
return 0;
p=head->next;//使p指向头结点后存储数据的第一个节点位置
printf("|----------------------------------------------------------------------------|\n");
printf("|\t\t\t\t5.查看学生数据\t\t\t\t |\n");
printf("|----------------------------------------------------------------------------|\n");
printf("请选择学生的学号:");
scanf("%d",&num);
while(num!=p->data.number)//当在已存储的学生数据中找不到想查看的学号时
{
p=p->next;//使p指向下一节点
if(p==head->next)//若查询完一遍后回到起始位置
return NULL;//返回NULL
}
return p;//找到想查看的节点返回该指针
}
int print_stu(Node *head)//显示学生数据
{
int flag,N;
Node *p;
if(head==NULL)
{
printf("学生数据未创建,暂不支持显示!\n");
return 0;
}
printf("|----------------------------------------------------------------------------|\n");
printf("|\t\t\t\t6.显示学生数据\t\t\t\t |\n");
printf("|----------------------------------------------------------------------------|\n");
printf("(1).顺序显示学生数据 \t\t(2).逆序显示学生数据\n(3).从某个学生开始顺序显示\t\t(4).从某个学生开始逆序显示\n");
printf("\n请选择显示方式(1/2/3/4):");
scanf("%d",&flag);
switch(flag)
{
case 1:
p=head->next;//使p指向第一个存数据节点的位置
printf("\t|---------------------------------------------------------------|\n");
printf("\t|学号\t|姓名\t|性别\t|随机\t|英语\t|图论\t|平均分\t\t|\n");
printf("\t|---------------------------------------------------------------|\n");
while(p!=head)//当p没有回到头指针时保持输出
{
printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
printf("\t|---------------------------------------------------------------|\n");
p=p->next;//输完一个节点数据后使p指向下一节点
}
break;
case 2:
p=head->prior;//使p指向最后一个存数据节点的位置
printf("\t|---------------------------------------------------------------|\n");
printf("\t|学号\t|姓名\t|性别\t|随机\t|英语\t|图论\t|平均分\t\t|\n");
printf("\t|---------------------------------------------------------------|\n");
while(p!=head)//当p没有回到头指针时
{
printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
printf("\t|---------------------------------------------------------------|\n");
p=p->prior;//输完一个节点数据后使p指向上一节点
}
break;
case 3:
p=find_stu(head);//找到指定节点位置然后返回该节点指针
N=p->data.number;//暂存找到的该节点学生学号
printf("\t|---------------------------------------------------------------|\n");
printf("\t|学号\t|姓名\t|性别\t|随机\t|英语\t|图论\t|平均分\t\t|\n");
printf("\t|---------------------------------------------------------------|\n");
printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
printf("\t|---------------------------------------------------------------|\n");
p=p->next;
while(p->data.number!=N)//当p没有回到自己位置时
{
if(p==head)//若p指向了头结点
{
p=p->next;//使p指向下一个节点
continue;//跳过此次循环
}
printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
printf("\t|---------------------------------------------------------------|\n");
p=p->next;//使p指向下一个节点
}
break;
case 4:
p=find_stu(head);//找到指定节点位置然后返回该节点指针
N=p->data.number;//暂存找到的该节点学生学号
printf("\t|---------------------------------------------------------------|\n");
printf("\t|学号\t|姓名\t|性别\t|随机\t|英语\t|图论\t|平均分\t\t|\n");
printf("\t|---------------------------------------------------------------|\n");
printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
printf("\t|---------------------------------------------------------------|\n");
p=p->prior;
while(p->data.number!=N)//当p没有回到自己位置时保持输出
{
if(p==head)//若p指向了头结点
{
p=p->prior;//使p指向上一个节点
continue;//跳过此次循环
}
printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
printf("\t|---------------------------------------------------------------|\n");
p=p->prior;//使p指向上一个节点
}
break;
default :
printf("输入选项序号错误!\n");
return 0;
}
}
int change_stu(Node *head)//改变学生数据
{
int n,m,t,flag=0;
Node *p,*temp;
if(head==NULL)
{
printf("学生数据未创建,暂不支持改变!\n");
return 0;
}
printf("|----------------------------------------------------------------------------|\n");
printf("|\t\t\t\t4.改变学生数据\t\t\t\t |\n");
printf("|----------------------------------------------------------------------------|\n");
p=find_stu(head);//找到指定改变的学生,然后返回该学生指针
while(p==NULL)//判断更改学号是否存在
{
printf("更改学号不存在!\n请重新输入:\n");
p=find_stu(head);
}
printf("%d号学生个人数据为:\n",p->data.number);//显示要更改学生的数据
printf("\t|---------------------------------------------------------------|\n");
printf("\t|学号\t|姓名\t|性别\t|随机\t|英语\t|图论\t|平均分\t\t|\n");
printf("\t|---------------------------------------------------------------|\n");
printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
printf("\t|---------------------------------------------------------------|\n");
temp=p;//暂存更改学生数据的指针
printf("确认更改该学生数据吗?(1/0):");
scanf("%d",&n);
if(n==1)
{
printf("|----------------------------------------------------------------------------|\n");
printf("1.学号 2.姓名 3.性别 4.随机成绩 5.英语成绩 6.图论成绩\n");
printf("|----------------------------------------------------------------------------|\n");
printf("请选择更改数据具体序号:");
scanf("%d",&m);
switch(m)
{
case 1:
while(1)
{
printf("更改学号为:");
scanf("%d",&p->data.number);
t=p->data.number;//暂存学号
p=p->next;//从下一个结点开始判断是否有相同的学号
while(p->data.number!=t)//判断是否有相同的学号
{
p=p->next;
if(p==temp)//查找完一遍回到原位置
{
flag=1;//无相同学号的标志
break;
}
}
if(flag==1)//不存在相同学号则跳出
break;
else
{
printf("学号已存在!\n请重新更改\n");
p=temp;//重新指向原位置
}
}
break;
case 2:
printf("更改姓名为:");
scanf("%s",p->data.name);
break;
case 3:
printf("更改性别为:");
scanf("%s",p->data.sex);
break;
case 4:
printf("更改随机成绩为:");
scanf("%f",&p->data.suiji);
break;
case 5:
printf("更改英语成绩为:");
scanf("%f",&p->data.English);
break;
case 6:
printf("更改图论成绩为:");
scanf("%f",&p->data.tulun);
break;
default:
printf("输入选择序号错误!\n");
return 0;
}
p->data.average=(p->data.suiji+p->data.English+p->data.tulun)/3;//更新平均分
printf("更改成功!该学生更改后的个人数据为:\n");//显示更改后的学生数据
printf("\t|---------------------------------------------------------------|\n");
printf("\t|学号\t|姓名\t|性别\t|随机\t|英语\t|图论\t|平均分\t\t|\n");
printf("\t|---------------------------------------------------------------|\n");
printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
printf("\t|---------------------------------------------------------------|\n");
}
else
return 0;
}
int del_stu(Node *head)//删除学生数据
{
int n,m;
Node *p;
if(head==NULL)
{
printf("学生数据未创建,暂不支持删除!\n");
return 0;
}
printf("|----------------------------------------------------------------------------|\n");
printf("|\t\t\t\t3.删除学生数据\t\t\t\t |\n");
printf("|----------------------------------------------------------------------------|\n");
p=find_stu(head);//找到指定删除的学生,然后返回该学生指针
while(p==NULL)//判断指定删除学生是否存在
{
printf("删除学号不存在!\n请重新输入:\n");
p=find_stu(head);
}
m=p->data.number;
printf("%d号学生个人数据为:\n",p->data.number);//在删除前显示要删学生的数据
printf("\t|---------------------------------------------------------------|\n");
printf("\t|学号\t|姓名\t|性别\t|随机\t|英语\t|图论\t|平均分\t\t|\n");
printf("\t|---------------------------------------------------------------|\n");
printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
printf("\t|---------------------------------------------------------------|\n");
printf("确认删除该学生数据吗?(1/0):");
scanf("%d",&n);
if(n==1)
{
p->prior->next=p->next;
p->next->prior=p->prior;
count=count-1;//删除完后学生个数自动减一
free(p);
printf("%d号学生数据已删除!\n",m);
}
else
return 0;
}
int add_stu(Node *head)//添加学生数据
{
int n;
Node *s,*p,*j;
s=(Node*)malloc(sizeof(Node));
if(head==NULL)
{
printf("学生数据未创建,暂不支持添加!\n");
return 0;
}
printf("|----------------------------------------------------------------------------|\n");
printf("|\t\t\t\t2.添加学生数据\t\t\t\t |\n");
printf("|----------------------------------------------------------------------------|\n");
printf("请输入学号:");
scanf("%d",&s->data.number);
j=judge(s,head);//判断添加的学号是否和已存在的学号相同
while(j!=NULL)
{
printf("添加学号已存在!\n请重新输入:\n");
scanf("%d",&s->data.number);
j=judge(s,head);//重新输入后再次判断
}
printf("请输入姓名(汉语):");
scanf("%s",s->data.name);
printf("请输入性别(男/女):");
scanf("%s",s->data.sex);
printf("请输入随机成绩:");
scanf("%f",&s->data.suiji);
printf("请输入图论成绩:");
scanf("%f",&s->data.tulun);
printf("请输入英语成绩:");
scanf("%f",&s->data.English);
s->data.average=(s->data.suiji+s->data.English+s->data.tulun)/3;
printf("\n1.在某位学生之前添加该学生数据\t\t2.在某位学生之后添加该学生数据\n");
printf("\n请选择序号:");
scanf("%d",&n);
if(n==1)
{
printf("\n请选择在哪位学生之前添加该学生数据:\n");
p=find_stu(head);//找指定的学生然后返回该学生指针
while(1)
{
if(p==NULL)
{
printf("没有该学生!\n请重新输入:\n");
p=find_stu(head);
}
else
break;
}
s->prior=p->prior;
p->prior->next=s;
s->next=p;
p->prior=s;
count++;//添加完后学生个数自动加一
printf("添加成功!该学生数据添加在%d号学生之前!\n",p->data.number);
}
else
{
printf("请选择在哪位学生之后添加该学生数据:\n");
p=find_stu(head);//找指定的学生然后返回该学生指针
while(1)
{
if(p==NULL)
{
printf("没有该学生!\n请重新输入:\n");
p=find_stu(head);
}
else
break;
}
p->next->prior=s;
s->next=p->next;
s->prior=p;
p->next=s;
count++;//添加完后学生个数自动加一
printf("添加成功!该学生数据添加在%d号学生之后!\n",p->data.number);
}
}
Node *creat_stu()//创建学生数据
{
Node *head,*p,*s,*sp;
int flag=1;
head=(Node*)malloc(sizeof(Node));
p=head;
printf("|----------------------------------------------------------------------------|\n");
printf("|\t\t\t\t1.创建学生数据\t\t\t\t |\n");
printf("|----------------------------------------------------------------------------|\n");
while(flag)
{
s=(Node*)malloc(sizeof(Node));
p->next=s;
s->prior=p;
p=s;
printf("请输入学号:");
scanf("%d",&s->data.number);
if(count>=1)//从第二个学生开始判断
{
sp=judge(s,head);//进入判断是否存在相同学号函数,若存在相同,返回NULL
while(sp!=NULL)
{
printf("输入学号已存在!\n请重新输入:\n");
scanf("%d",&s->data.number);
sp=judge(s,head);//重新输入后再次判断
}
}
while(s->data.number<0||s->data.number==0)
{
printf("学号必须大于零!\n请重新输入:");
scanf("%d",&s->data.number);
}
printf("请输入姓名(汉语):");
scanf("%s",s->data.name);
printf("请输入性别(男/女):");
scanf("%s",s->data.sex);
printf("请输入随机成绩:");
scanf("%f",&s->data.suiji);
printf("请输入图论成绩:");
scanf("%f",&s->data.tulun);
printf("请输入英语成绩:");
scanf("%f",&s->data.English);
s->data.average=(s->data.suiji+s->data.English+s->data.tulun)/3;//平均成绩
count++;//输入完一个学生个数自动加一
printf("\n是否继续输入数据(1/0):");
scanf("%d",&flag);
printf("\n");
}
head->prior=s;//连接首尾,构成双循环
p->next=head;
printf("创建成功!创建了%d个学生数据!\n",count);
return head;//返回创建成功后的头指针
}
int main()//主函数
{
Node *head,*p;
int flag;
char ch;
head=NULL;
show();
while(1)
{
system("color 3c");
printf("\n\t\t\t欢迎进入重邮研究生管理系统!\n");//显示主页面
printf("\t\tWelcome To Postgraduates' System of CQUPT!\n");
printf("|----------------------------------------------------------------------------|\n");
printf("|1创建学生数据\t\t\t2添加学生数据\t\t\t3删除学生数据|\n");
printf("|4改变学生数据\t\t\t5查看学生数据\t\t\t6显示学生数据|\n");
printf("|0退出程序\t\t\t\t\t\t\t\t |\n");
printf("|----------------------------------------------------------------------------|\n");
printf("\n请您选择操作方式:");
scanf("%d",&flag);
switch(flag)
{
case 0:system("cls");//退出程序
printf("\n\n\n\n\n\n\n\n|----------------------------------------------------------------------------|\n");
printf("|\t\t\t感谢您使用重邮研究生管理系统!\t\t\t |\n");
printf("|----------------------------------------------------------------------------|\n");
return 0;
case 1:system("cls");
head=creat_stu();//创建学生数据
getchar();
printf("\n按回车键返回主页面:");
if(ch=getchar())
system("cls");
break;
case 2:system("cls");
add_stu(head);//添加学生数据
getchar();
printf("\n按回车键返回主页面:");
if(ch=getchar())
system("cls");
break;
case 3:system("cls");
del_stu(head);//删除学生数据
getchar();
printf("\n按回车键返回主页面:");
if(ch=getchar())
system("cls");
break;
case 4:system("cls");
change_stu(head);//改变学生数据
getchar();
printf("\n按回车键返回主页面:");
if(ch=getchar())
system("cls");
break;
case 5:system("cls");
p=find_stu(head);//查看学生数据
if(p!=NULL)
{
printf("\t|---------------------------------------------------------------|\n");
printf("\t|学号\t|姓名\t|性别\t|随机\t|英语\t|图论\t|平均分\t\t|\n");
printf("\t|---------------------------------------------------------------|\n");
printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
printf("\t|---------------------------------------------------------------|\n");
}
else
printf("没有学生数据!\n");
getchar();
printf("\n按回车键返回主页面:");
if(ch=getchar())
system("cls");
break;
case 6:system("cls");
print_stu(head);//显示学生数据
getchar();
printf("\n按回车键返回主页面:");
if(ch=getchar())
system("cls");
break;
default:
printf("请重新输入序号!\n");//序号输入错误
break;
}
}
}
显示如下:
输入账号密码界面
显示菜单界面
创建
添加
删除
更改
查看
显示
退出