(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表示。高老师教授0李明一班2^王平二班2^^李老师副教授0^白梅二班1^李刚一班2^^图3导师制用广义表实现示例源代码:#includestdio.h#includestdlib.h#includestring.htypedefstructGLNode//定义存储中缀表达式的结点类型{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;//非首结点elsehead=s;//首结点的处理p=s;r=q=s;//a在此等于m,主要是处理本科生直属于导师的情况break;case1:if(p-ptr.tp)q-ptr.hp=s;//非首结点的处理elseq-ptr.tp=s;//首结点的处理q=s;r=s;break;case2:if(q-ptr.tp)r-ptr.hp=s;//非首结点的处理elser-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;