题目如上(九院版,被老师要求选这个题目做,不知道还有没有别的学校是这种题目,都可以相互借鉴hh)
代码写的有冗余,结构体应该有三个,一个学生,一个课程,一个十字链表的结构体,如果公用十字链表的结构体,学生和课程会有很多指针用不上,但是我懒,不想改了,将就着看吧......
代码如下:
//课程编号为1——2500的编号
//学号为十位数字
#include<cstdio>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<map>
using namespace std;
const int MAXstu=40010,MAXcou=2510,mod=1e5;
typedef long long LL;
bool st1[MAXstu];
bool st2[MAXcou];//初始化学生和课程的姓名,方便生成整套的大数据
char stuNames[10][20]={"Alice","Bob","Charlie","David","Emma","Frank","Grace","Henry","Ivy","Jack"};
char couNames[10][20]={"Math","Physics","Chemistry","Biology","History","Literature","Art","Music","Computer Science","Geography"};struct Node
{LL stuid;//学生学号char stuname[20];//学生姓名int couid;//课程编号char couname[20];//课程名struct Node *prestu;//指向学生前驱节点struct Node *stu;//指向学生后继节点struct Node *precou;//指向课程前驱节点struct Node *cou;//指向课程后继节点
};
struct Node students[MAXstu],courses[MAXcou]; //函数声明
void Add_Stu();//添加学生
void Add_Cou();//添加课程
void ChooseCourse();//学生进行选课
void printStuCou();//输出学生所选课程信息
void printCouStu();//输出课程被学生选的信息
void DeleteStu();//删除学生信息
void DeleteCou();//删除课程信息
int hash1(long long);//学生学号哈希 LL hashid[MAXstu]={0};
int hash1(LL id){//学生学号哈希,采用除留余数法int k=id%MAXstu;while(hashid[k]!=id&&hashid[k]!=0){//线性探测k++;if(k==MAXstu)k=0;//循环数组}hashid[k]==id;return k;
}
void Add_Stu(char name[],LL id)//添加学生
{int k=hash1(id);//学号的哈希值if(st1[k]){printf("该学生已存在,请勿重复添加!!!\n");return;}st1[k]=true;strcpy(students[k].stuname,name);//姓名放里面students[k].stuid=id;//学号放里面students[k].cou=NULL;//该学生选的课程链表初始化为空students[k].precou=NULL; printf("添加学生成功!!!\n");
}
void Add_Cou(char name[],int id)//添加课程
{if(st2[id]){printf("该课程已存在,请勿重复添加!!!\n");return;}st2[id]=true;strcpy(courses[id].couname,name);//课程名courses[id].couid=id;//课程编号courses[id].stu=NULL;//选该课程的学生链表初始化为空courses[id].prestu=NULL;printf("添加课程成功!!!\n");
}
void ChooseCourse(LL stuid,int couid)//学生进行选课
{Node *t=(Node*)malloc(sizeof(Node));//申请一个新的节点 t->stuid=stuid,t->couid=couid;strcpy(t->couname,courses[t->couid].couname);//课程名 //四个指针域都为空 t->cou=NULL;t->precou=NULL;t->stu=NULL;t->prestu=NULL;int k=hash1(t->stuid);//学号的哈希值 if(!st1[k]){printf("该学生不存在,输入错误,选课失败!!!\n"); return;}if(!st2[t->couid]){printf("该课程不存在,输入错误,选课失败!!!\n");return;}strcpy(t->stuname,students[k].stuname);//学生姓名 //给学生连节点Node *p=students[k].cou;Node *q;if(p==NULL){students[k].cou=t;}else{q=p,p=p->cou;while(p!=NULL)q=p,p=p->cou;q->cou=t;t->precou=q;}//给课程连节点p=courses[t->couid].stu;if(p==NULL){courses[t->couid].stu=t;}else{q=p,p=p->stu;while(p!=NULL)q=p,p=p->stu;q->stu=t;t->prestu=q;}printf("学号为%010lld的学生成功选择了课程编号为%d的课程!!!\n",t->stuid,t->couid);
}void printStuCou()//输出学生所选课程信息
{LL id;printf("请输入您要查找学生的学号:"); scanf("%lld",&id);int k=hash1(id);if(!st1[k]){cout<<"该学生不存在,输入错误!!!"<<endl;return;}Node *p=students[k].cou;if(p==NULL){cout<<"该学生暂未选择任何课程!!!"<<endl;return;}printf("学生名为%s,学号为%010lld的学生所选的课程如下:\n",students[k].stuname,id);while(p!=NULL){printf("课程编号:%04d 课程名:%s\n",p->couid,p->couname);p=p->cou;}
}
void printCouStu()//输出课程被学生选的信息
{int id;printf("请输入您要查找的课程编号:");scanf("%d",&id);if(!st2[id]){cout<<"该课程不存在,输入错误!!!"<<endl;return;}Node *p=courses[id].stu;if(p==NULL){cout<<"该课程暂未被任何学生选择!!!"<<endl; return;}printf("课程名为%s,课程编号为%d的课程被选的信息如下:\n",courses[id].couname,id);while(p!=NULL){printf("学号:%010lld 学生姓名:%s\n",p->stuid,p->stuname);p=p->stu; }
}
void DeleteStu()//删除学生信息
{LL id;printf("请输入您要删除的学生学号:");scanf("%lld",&id);int k=hash1(id);if(!st1[k]){printf("该学生不存在,删除失败!!!\n");return;} st1[k]=false;//标记删除 Node *p=students[k].cou;while(p!=NULL){if(p==courses[p->couid].stu)courses[p->couid].stu=p->stu;else{if(p->prestu!=NULL)p->prestu->stu=p->stu;if(p->stu!=NULL)p->stu->prestu=p->prestu;}Node *t=p;p=p->cou;delete(t);}printf("学号为%010lld的学生删除成功!!!\n",id);
}void DeleteCou()//删除课程信息
{int id;printf("请输入你要删除的课程编号:");scanf("%d",&id);if(!st2[id]){printf("不存在该课程,删除失败!!!\n");return;}st2[id]=false;//标记删除Node *p=courses[id].stu;while(p!=NULL){int k=hash1(p->stuid);if(p==students[k].cou)students[k].cou=p->cou;else{if(p->precou!=NULL)p->precou->cou=p->cou;if(p->cou!=NULL)p->cou->precou=p->precou;}Node *t=p;p=p->stu;delete(t);}printf("课程编号为%d的课程删除成功!!!\n",id);
}void initializeData()//初始化,随机生成学生和课程及学生选课的数据
{srand(time(NULL));// 设置随机种子//生成随机学生数据,rand()最大可生成32767,9999999999/32767=305185 for (int i=0;i<MAXstu;++i){LL id=(LL)305185*rand()%9999999999+1; // 随机生成学生学号char name[20];strcpy(name,stuNames[rand()%10]); // 从学生姓名数组中随机选择一个姓名Add_Stu(name,id);//添加学生}// 生成随机课程数据for (int i=0;i<MAXcou;i++){int id=rand()%2500+1;//随机生成课程编号char name[20];strcpy(name,couNames[rand()%10]);Add_Cou(name,id);//添加课程 }//随机选择部分学生并为其分配已选的课程for (int i=0;i<MAXstu/2;i++)//假设有一半的学生已经完成选课 {int k=rand()%40000+1; //随机选择学生学号的哈希值 if(!st1[k])continue;//如果该学生不存在,则直接进入下层循环 LL stuid=students[k].stuid;//记录学生编号 int numCourses=rand()%5+1; //随机生成已选课程的数量,假设每个学生选 1 到 5 门课for(int j=0;j<numCourses;j++){int couid=rand()%2500+1; // 随机生成课程编号ChooseCourse(stuid,couid);//学生选课}}
}int main()
{//initializeData();//初始化数据,不加这句话就要自己手动初始化了while(1){cout<<"********************************"<<endl;cout<<"*====请选择以下数字进行操作====*"<<endl;cout<<"* 0 退出系统 *"<<endl;cout<<"* 1 添加学生信息 *"<<endl;cout<<"* 2 添加课程信息 *"<<endl;cout<<"* 3 删除学生信息 *"<<endl;cout<<"* 4 删除课程信息 *"<<endl;cout<<"* 5 学生进行选课 *"<<endl;cout<<"* 6 输出课程所选学生名单 *"<<endl;cout<<"* 7 输出学生选课课程清单 *"<<endl;cout<<"********************************"<<endl;int choice;printf("请输入您要做的操作:");scanf("%d",&choice);switch(choice){case 0:exit(0);case 1:{int op=1;while(op){char name[20];LL id;printf("请输入要添加的学生姓名和学号(学号小于等于十位数):");scanf("%s%lld",name,&id);Add_Stu(name,id);printf("继续添加学生请输入1,否则输出0,请输入:");scanf("%d",&op);}break;}case 2:{int op=1;while(op){int id;char name[20];printf("请输入要添加的课程编号(课程编号小于等于四位数)和课程名:");scanf("%d%s",&id,name);Add_Cou(name,id);printf("继续添加课程请输入1,否则输出0,请输入:");scanf("%d",&op);}break;}case 3:DeleteStu();break;case 4:DeleteCou();break;case 5:{int op=1;while(op){LL stuid;int couid;scanf("%lld%d",&stuid,&couid);ChooseCourse(stuid,couid);printf("继续选课请输入1,否则输出0,请输入:"); scanf("%d",&op);}break;}case 6:printCouStu();break;case 7:printStuCou();break;}}return 0;
}