C语言实现本科生导师制问题.docx
- 文档编号:8861318
- 上传时间:2023-05-15
- 格式:DOCX
- 页数:19
- 大小:31.35KB
C语言实现本科生导师制问题.docx
《C语言实现本科生导师制问题.docx》由会员分享,可在线阅读,更多相关《C语言实现本科生导师制问题.docx(19页珍藏版)》请在冰点文库上搜索。
C语言实现本科生导师制问题
(2)本科生导师制问题
问题描述
在高校的教学改革中,有很多学校实行了本科生导师制。
一个班级的学生被分给几个老师,每个老师带n个学生,如果该老师还带研究生,那么研究生也可直接带本科生。
本科生导师制问题中的数据元素具有如下形式:
●导师带研究生
(老师,((研究生1,(本科生1,…,本科生m1)),(研究生2,(本科生1,…,本科生m2))…))
●导师不带研究生
(老师,(本科生1,…,本科生m))
导师的自然情况只包括姓名、职称;研究生的自然情况只包括姓名、班级;本科生的自然情况只包括姓名、班级。
基本要求
要求完成以下功能:
●建立:
建立导师广义表。
●插入:
将某位本科生或研究生插入到广义表的相应位置。
●删除:
将某本科生或研究生从广义表中删除。
●查询:
查询导师、本科生(研究生)的情况。
●统计:
某导师带了多少个研究生和本科生。
●输出:
将某导师所带学生情况输出。
●退出:
程序结束。
设计提示
本实验使用的数据结构是广义表,广义表采用头尾链表存储结构来实现。
定义教师、学生结点结构体如下:
typedefstructGLNode
{
charname[100];/*教师或学生的姓名*/
charprof[100];/*教师结点表示职称,学生结点表示班级*/
inttype;/*结点类型:
0-教师,1-研究生,2-本科生*/
struct{structGLNode*hp,*tp;}ptr;
/*hp指向同级的下一结点,tp指向下级的首结点*/
}GList;
人员信息的表示形式为:
高老师-教授-0、李刚-二班-1、李明-二班-2.
人员信息中的姓名、职称、班级、人员类型用“-”隔开,如高老师-教授-0,“高老师”表示姓名,“教师”表示职称,“0”表示人员的类型是教师;李刚-二班-1,“李刚”表示姓名,“二班”表示班级,“1”表示人员的类型是研究生;李明-二班-2,“李明”表示姓名,“二班”表示班级,“2”表示人员的类型是本科生。
广义表((高老师-教授-0,(李明-一班-2,王平-二班-2)),(李老师-副教授-0,(白梅-二班-1,(李刚-一班-2)))可以用图3表示。
图3导师制用广义表实现示例
源代码:
#include
#include
#include
typedefstructGLNode//定义存储中缀表达式的结点类型
{charname[100];
charprof[100];
inttype;
struct{structGLNode*hp,*tp;}ptr;/*hp指向同级的下一结点,tp指向下级的首结点*/
}GList;
GList*GListCreate()//建立广义表
{GList*head,*p,*q,*s,*r;//简要介绍:
head指向头结点;p指向导师结点;q指向研究生结点;r指向本科生节点;s指向新建立的节点
inti,j,b;
charstr[100];
b=1;
head=p=q=r=s=NULL;
while(b)
{printf("请输入人员信息");
scanf("%s",str);
s=(GList*)malloc(sizeof(GList));
if(!
s)printf("申请空间失败!
");
for(j=0,i=0;str[i]!
='-';j++,i++)//将字符串中的学生信息转化成学生结点
s->name[j]=str[i];
s->name[j]='\0';
i=i+1;
for(j=0;str[i]!
='-';j++,i++)
s->prof[j]=str[i];
s->prof[j]='\0';
i=i+1;
s->type=str[i]-48;
s->ptr.hp=NULL;
s->ptr.tp=NULL;
switch(s->type)
{case0:
if(head)
p->ptr.hp=s;//非首结点
else
head=s;//首结点的处理
p=s;
r=q=s;//a在此等于m,主要是处理本科生直属于导师的情况
break;
case1:
if(p->ptr.tp)
q->ptr.hp=s;//非首结点的处理
else
q->ptr.tp=s;//首结点的处理
q=s;
r=s;
break;
case2:
if(q->ptr.tp)
r->ptr.hp=s;//非首结点的处理
else
r->ptr.tp=s;//首结点的处理
r=s;
break;
default:
printf("结点有误");
break;
}
printf("输入1:
继续添加;输入0:
录入结束");
scanf("%d",&b);
}
returnhead;
}
voidInquire(GList*head)//查询信息
{charn[100];
GList*p,*q,*r;
intresult;
result=0;
p=head;
printf("\n请输入所查询人员的姓名:
\n");
scanf("%s",n);
while(p!
=NULL&&result==0)
{q=p->ptr.tp;
if(!
strcmp(p->name,n))
{printf("\n查询结果:
姓名:
%s职称:
%s类型:
导师\n",p->name,p->prof);
result=1;
}
else
{if(q->type==2)//该导师带本科生
{r=q;
while(r!
=NULL)
{if(!
strcmp(r->name,n))
{printf("\n查询结果:
姓名:
%s班级:
%s类型:
本科生\n",r->name,r->prof);
printf("所属导师:
姓名:
%s职称:
%s\n",p->name,p->prof);
result=1;
}
r=r->ptr.hp;
}
}
else
{while(q!
=NULL)
{r=q->ptr.tp;
if(!
strcmp(q->name,n))
{printf("\n查询结果:
姓名:
%s班级:
%s类型:
研究生\n",q->name,q->prof);
printf("所属导师:
姓名:
%s职称:
%s\n",p->name,p->prof);
result=1;
}
while(r!
=NULL)
{if(!
strcmp(r->name,n))
{printf("\n查询结果:
姓名:
%s班级:
%s类型:
本科生\n",r->name,r->prof);
printf("所属导师:
姓名:
%s职称:
%s\n",p->name,p->prof);
printf("所属导师生:
姓名:
%s班级:
%s\n",q->name,q->prof);
result=1;
}
r=r->ptr.hp;
}
q=q->ptr.hp;
}
}
p=p->ptr.hp;
}
}
if(!
result)printf("查无此人!
\n");
printf("\n");
}
GList*StudentInsert(GList*head)//插入学生
{charstudent[100],teacher[100],graduate[100];
GList*s,*p,*q,*r;
inti,j;
p=head;
printf("请输入待插入学生信息,如:
李刚-二班-1\n");
scanf("%s",student);
s=(GList*)malloc(sizeof(GList));
if(!
s)printf("申请空间失败!
");
for(j=0,i=0;student[i]!
='-';j++,i++)//将字符串中的学生信息转化成学生结点
s->name[j]=student[i];
s->name[j]='\0';
i=i+1;
for(j=0;student[i]!
='-';j++,i++)
s->prof[j]=student[i];
s->prof[j]='\0';
i=i+1;
s->type=student[i]-48;
s->ptr.hp=NULL;
s->ptr.tp=NULL;
printf("请输入所属导师姓名:
\n");
scanf("%s",teacher);
while(p&&strcmp(p->name,teacher))
p=p->ptr.hp;
if(!
p)
printf("此导师不存在,不能插入!
\n");
else
{switch(s->type)
{case1:
if(!
p->ptr.tp)
{p->ptr.tp=s;
printf("插入成功!
\n");
}
else
{if(p->ptr.tp->type==2)
printf("该导师只能带本科生,因此不能将研究生插入!
\n");
else
{q=p->ptr.tp;
while(q->ptr.hp)
q=q->ptr.hp;
q->ptr.hp=s;
printf("插入成功!
\n");
}
}
break;
case2:
if(!
p->ptr.tp)
{p->ptr.tp=s;
printf("插入成功!
\n");
}
else
{switch(p->ptr.tp->type)
{case1:
printf("请输入所属研究生姓名:
\n");//导师带研究生
scanf("%s",graduate);
q=p->ptr.tp;
while(q&&strcmp(q->name,graduate))
q=q->ptr.hp;
if(!
q)
printf("该研究生不存在,不能插入!
\n");
else
{if(!
q->ptr.tp)
{q->ptr.tp=s;
printf("插入成功!
\n");
}
else
{r=q->ptr.tp;
while(r->ptr.hp)
r=r->ptr.hp;
r->ptr.hp=s;
printf("插入成功!
\n");
}
}
break;
case2:
if(!
p->ptr.tp)//导师带本科生
{p->ptr.tp=s;
printf("插入成功!
\n");
}
else
{r=p->ptr.tp;
while(r->ptr.hp)
r=r->ptr.hp;
r->ptr.hp=s;
printf("插入成功!
\n");
}
break;
default:
printf("结点有误");
break;
}
}
break;
default:
printf("结点有误");
break;
}
}
returnhead;
}
GList*StudentDelete(GList*head)//删除学生
{charstudent[100];
GList*s,*p,*q,*r,*t;
inti,j,result;
result=0;
p=q=r=head;
printf("请输入待删除学生信息,如:
李刚-二班-1\n");
scanf("%s",student);
s=(GList*)malloc(sizeof(GList));
if(!
s)printf("申请空间失败!
");
for(j=0,i=0;student[i]!
='-';j++,i++)//将字符串中的学生信息转化成学生结点
s->name[j]=student[i];
s->name[j]='\0';
i=i+1;
for(j=0;student[i]!
='-';j++,i++)
s->prof[j]=student[i];
s->prof[j]='\0';
i=i+1;
s->type=student[i]-48;
s->ptr.hp=NULL;
s->ptr.tp=NULL;
switch(s->type)
{case1:
do
{if(p->ptr.tp->type==1)
{q=p->ptr.tp;
t=p;
while(q&&strcmp(q->name,s->name))
{t=q;
q=q->ptr.hp;
}
if(!
strcmp(q->name,s->name))
{if(q->ptr.tp)
{printf("此研究生下有本科生,请先将本科生移至别处,再删除此研究生");
result=2;
break;
}
else
{result=1;
if(t->type==0)t->ptr.tp=q->ptr.hp;
elset->ptr.hp=q->ptr.hp;
free(q);
}
}
}
p=p->ptr.hp;
}while(p!
=NULL&&result==0);
break;
case2:
do
{if(!
p->ptr.tp)
{p=p->ptr.hp;
continue;
}
else
{switch(p->ptr.tp->type)
{case1:
q=p->ptr.tp;//导师带研究生
while(q&&!
result)
{t=q;
r=t->ptr.tp;
while(r&&strcmp(r->name,s->name))
{t=r;
r=r->ptr.hp;
}
if(r)
{result=1;
if(t->type==1)t->ptr.tp=r->ptr.hp;
elset->ptr.hp=r->ptr.hp;
free(r);
}
elseq=q->ptr.hp;
}
break;
case2:
r=p->ptr.tp;//导师带本科生
t=p;
while(!
result&&r)
{while(r&&strcmp(r->name,s->name))
{t=r;
r=r->ptr.hp;
}
if(r)
{result=1;
if(t->type==0)t->ptr.tp=r->ptr.hp;
elset->ptr.hp=r->ptr.hp;
free(r);
}
}
break;
default:
break;
}
}
p=p->ptr.hp;
}while(p!
=NULL&&result==0);
break;
default:
printf("结点有误");
break;
}
if(result==0)printf("查无此人");
returnhead;
}
voidStudentCount(GList*head)//统计导师的研究生、本科生人数
{GList*p,*q,*r;
intgraduate=0,ungraduate=0;
charteacher[100];
printf("请输入老师姓名:
\n");
scanf("%s",teacher);
p=head;
while(p&&strcmp(p->name,teacher))
{p=p->ptr.hp;
}
if(!
p)
printf("查无此导师");
else
{if(p->ptr.tp)
{if(p->ptr.tp->type==1)
{q=p->ptr.tp;
while(q)
{graduate++;
r=q->ptr.tp;
while(r)
{ungraduate++;
r=r->ptr.hp;
}
q=q->ptr.hp;
}
}
else
{r=p->ptr.tp;
while(r)
{ungraduate++;
r=r->ptr.hp;
}
}
}
printf("该导师带的研究生数为%d",graduate);
printf("该导师带的本科生数为%d",ungraduate);
}
}
voidGListPrint(GList*head)//输出广义表
{GList*p,*q,*r;
p=head;
while(p)
{printf("%s-%s-%d",p->name,p->prof,p->type);
if(p->ptr.tp)//导师带学生
{switch(p->ptr.tp->type)
{case1:
q=p->ptr.tp;//导师带研究生
while(q)
{printf("%s-%s-%d",q->name,q->prof,q->type);
if(q->ptr.tp)//研究生带本科生
{r=q->ptr.tp;
while(r)
{printf("%s-%s-%d",r->name,r->prof,r->type);
r=r->ptr.hp;
}
}
q=q->ptr.hp;
}
break;
case2:
r=p->ptr.tp;//导师直接带本科生
while(r)
{printf("%s-%s-%d",r->name,r->prof,r->type);
r=r->ptr.hp;
}
break;
default:
printf("结点有误");
break;
}
}
p=p->ptr.hp;
printf("\n");
}
}
voidmain()
{intb;
GList*Head;
Head=NULL;
printf("1.建立广义表\n");
Head=GListCreate();
do
{printf("2.插入学生\n");
printf("3.删除学生\n");
printf("4.查询信息\n");
printf("5.统计导师的研究生、本科生人数\n");
printf("6.输出广义表\n");
printf("0.退出\n");
scanf("%d",&b);
switch(b)
{
case2:
Head=StudentInsert(Head);
break;
case3:
Head=StudentDelete(Head);
break;
case4:
Inquire(Head);break;
case5:
StudentCount(Head);
break;
case6:
GListPrint(Head);
break;
case0:
break;
default:
printf("选择有误");
break;
}
if(b==0)break;
}while
(1);
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 实现 本科生 导师制 问题