题目如上(九院版,被老师要求选这个题目做,不知道还有没有别的学校是这种题目,都可以相互借鉴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;
}