选课清单--数据结构课程设计(十字链表+哈希表实现)

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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/698650.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何有效处理服务器后台密码暴露

服务器后台密码的暴露是信息安全领域中的严重事件&#xff0c;它可能引发未经授权的数据访问、恶意软件植入或系统功能滥用等一系列问题。本文将探讨几种处理服务器后台密码暴露的有效策略&#xff0c;包括紧急响应步骤、密码安全增强措施及长期预防机制&#xff0c;并提供实际…

【LeetCode 第 401 场周赛】K秒后第 N 个元素的值

文章目录 1. K秒后第 N 个元素的值&#x1f197; 1. K秒后第 N 个元素的值&#x1f197; 题目链接&#x1f517; &#x1f427;解题思路&#xff1a; 前缀和 小规律&#x1f34e; &#x1f34e; 从上图观察可知&#xff0c;规律一目了然&#xff0c;arr[i] arr[i] 对上一…

【机器学习】基于3D CNN通过CT图像分类预测肺炎

1. 引言 1.1. 研究背景 在医学诊断中&#xff0c;医生通过分析CT影像来预测疾病时&#xff0c;面临一些挑战和局限性&#xff1a; 图像信息的广度与复杂性&#xff1a; CT扫描生成的大量图像对医生来说既是信息的宝库也是处理上的负担。每组CT数据可能包含数百张切片&#xf…

代码随想录算法训练营第36期DAY57

DAY57 今天的好消息&#xff1a;能去华五。 1143最长公共子序列 Code: class Solution {public: int longestCommonSubsequence(string text1, string text2) { vector<vector<int>> dp(text1.size()1,vector<int>(text2.size()1,0)); f…

【PowerDesigner】CDM生成PDM

目录 &#x1f30a;1. PowerDesigner简介 &#x1f30d;1.1 常用模型文件 &#x1f30d;1.2 PowerDesigner使用环境 &#x1f30a;2. CDM生成PDM ​​​​​​​&#x1f30a;3. 研究心得 &#x1f30a;1. PowerDesigner简介 &#x1f30d;1.1 常用模型文件 主要使用Pow…

家具板材ENF级甲醛释放量检测 板材甲醛含量测定

ENF级甲醛释放量检测 ENF级是指甲醛释放量非常低的板材&#xff0c;它代表了无醛添加的最高级别。根据最新的国家标准GB/T 39600-2021&#xff0c;ENF级板材的甲醛释放量不得超过0.025 mg/m。这个标准比欧洲的E1级&#xff08;甲醛释放量≤0.124 mg/m&#xff09;和美国的P2标准…

2024年,计算机相关专业还值得选择

随着2024年高考落幕&#xff0c;数百万高三学生又将面临人生中的重要抉择&#xff1a;选择大学专业。在这个关键节点&#xff0c;计算机相关专业是否仍是“万金油”的选择&#xff1f;在过去很长一段时间里&#xff0c;计算机科学与技术、人工智能、网络安全、软件工程等专业一…

移动端浏览器的扫描二维码实现(vue-qrcode-reader与jsQR方式)

1. 实现功能 类似扫一扫的功能&#xff0c;自动识别到画面中的二维码并进行识别&#xff0c;也可以选择从相册中上传。 2. 涉及到的一些插件介绍 vue-qrcode-reader 一组用于检测和解码二维码的Vue.js组件 jsQR 一个纯粹的javascript二维码阅读库&#xff0c;该库接收原始…

使用 3D 图形 API 在 C# 中将 PLY 转换为 OBJ

OBJ和PLY是一些广泛使用的 3D 文件格式&#xff0c;易于编写和读取。这篇博文演示了如何以编程方式在 C# 中将 PLY 转换为 OBJ。此外&#xff0c;它还介绍了一种用于 3D 文件格式转换的在线3D 转换器。是的&#xff0c;Aspose.3D for .NET为程序员和非程序员提供了此功能来执行…

MTK烧录USB驱动下载

下载链接 https://www.catalog.update.microsoft.com/Search.aspx?qMediaTek%20USB%20Port 驱动安装教程 https://miuiver.com/install-official-mediatek-driver/

交友系统定制版源码 相亲交友小程序源码全开源可二开 打造独特的社交交友系统

交友系统源码的实现涉及到多个方面&#xff0c;包括前端页面设计、后端逻辑处理、数据库设计以及用户交互等。以下是一个简单的交友系统源码实现的基本框架和关键步骤: 1.数据库设计:用户表:存储用户基本信息&#xff0c;如用户ID、用户名、密码、头像、性别、年龄、地理位置…

SpringCloud 前端-网关-微服务-微服务间实现信息共享传递

目录 1 网关获取用户校验信息并保存至请求头&#xff08;前端-网关&#xff09; 2 微服务获取网关中的用户校验信息&#xff08;网关-微服务&#xff09; 2.1 一般的做法是在公共的module中添加&#xff0c;此处示例为common 公共配置module中添加 2.2 定义拦截器 2.3 定义…

什么是微控制器中的欠压复位?如何防止误断电

微控制器的“掉电”是指电源电压部分暂时降低到可靠运行所需的水平以下。许多微控制器都有一个保护电路&#xff0c;可以检测电源电压何时低于此水平&#xff0c;并将设备置于复位状态&#xff0c;以确保电源恢复时正确启动。此操作称为“欠压复位”或 BOR。类似的功能称为低电…

数据不归路?文件清理的后悔药,2个文件恢复技巧

手机已成为我们生活中不可或缺的重要工具&#xff0c;它不仅仅是一个通讯设备&#xff0c;更是我们存储个人信息、工作文件、照片和视频等宝贵资料的仓库。然而&#xff0c;生活中的意外总是难以预料&#xff0c;有时候我们可能会不小心删除重要的文件&#xff0c;或者因为手机…

JVS规则引擎实战:如何轻松接入本地数据库数据

在当今数据驱动的时代&#xff0c;有效地接入和利用各种数据源是企业和组织实现智能化、自动化决策的关键。JVS-RULES通过支持多种数据形态&#xff0c;为用户提供了一个统一的数据接入平台&#xff0c;使不同来源的数据能够被整合并用于规则判断。接下来我给大家详细介绍如何通…

鸿蒙轻内核M核源码分析系列二十 Newlib C

LiteOS-M内核LibC实现有2种&#xff0c;可以根据需求进行二选一&#xff0c;分别是musl libC和newlibc。本文先学习下Newlib C的实现代码。文中所涉及的源码&#xff0c;均可以在开源站点https://gitee.com/openharmony/kernel_liteos_m 获取。 使用Musl C库的时候&#xff0c…

CSS之块浮动

在盒子模型的基础上就可以对网页进行设计 不知道盒子模型的可以看前面关于盒子模型的内容 而普通的网页设计具有一定的原始规律,这个原始规律就是文档流 文档流 标签在网页二维平面内默认的一种排序方式,块级标签不管怎么设置都会占一行,而同一行不能放置两个块级标签 行级…

Ubuntu编译虚幻引擎工程

前言 最近研究了一下在ubuntu编译虚幻引擎&#xff0c;发现确实做得很好&#xff0c;编译非常简单&#xff0c;这里记录一下。 下载虚幻引擎源码 源码下载地址如下https://www.unrealengine.com/zh-CN/linux 选择合适的版本即可&#xff0c;我这里选择的是UE5.1 安装dotnet驱动…

前端JS必用工具【js-tool-big-box】学习,获取当前浏览器向上滚动还是向下滚动,获取当前距离顶部和底部的距离

这一小节&#xff0c;我们说一下 js-tool-big-box 添加的最新工具方法&#xff0c;在日常前端开发工作中&#xff0c;如果网页很长&#xff0c;我们就需要获取当前浏览器是在向上滚动&#xff0c;还是向下滚动。如果向上滚动&#xff0c;滚动到0的时候呢&#xff0c;需要做一些…

金智易表通流程设置的若干问题

1、审批节点的审批人取应用权限组&#xff0c;权限组内任一人审批即可通过 在流程节点的主要配置环节&#xff0c;选择候选组 二、已审菜单要求看到自己审过的也能看到别人审过的&#xff0c;即能看到所有已审的记录 管理设置中取消按钮对流程的依赖&#xff0c;不根据流程审批…