c++采用链式存储完成学生信息的管理

#include<iostream>
#include<string>
#include<fstream>
using namespace std;

struct score     //定义存放学生信息的结点
{
	int num;      //学号 
	string name;   //姓名 
	string major;   //专业
	string classes;  //班级
	string sex;   //性别 
	int age;   //年龄 
	struct score* next;  //next为指向下一结点的指针 
};
struct score* head;  //指向链表头结点的指针
struct score* head2;  //指向链表头结点的指针
struct score* head3;  //指向链表头结点的指针
int studentSum = 0;  //学生总人数
class record
{
public:
	struct score* InsertRecord(struct score* h);//插入学生信息 
	struct score* DeleteRecord(struct score* h);//删除学生信息 

	struct score* AUpdateRecord(struct score* h, int  x);//修改学生信息 

	void FindRecord(struct score* h, string  x); //根据学生姓名查询学生信息 
	void FindRecord(struct score* h, int x);     //根据学生学号查询学生信息 
	void MajorRecordFind(struct score* h, string x);     //统计指定专业的学生人数,并显示全部指定专业学生信息 
	void ClasRecordFind(struct score* h, string x);     //统计指定班级的学生人数,并显示全部指定班级学生信息 
	void AgeRecordFind(struct score* h, int x);     //统计指定年龄的学生人数,并显示全部指定年龄学生信息 
	void SexRecordFind(struct score* h, string x);     //统计指定性别的学生人数,并显示全部指定性别学生信息 

	void PrintRecord(struct score* h);       //输出所有学生信息
	void SaveRecordFile(struct score* h);     //保存学生信息到文件 
	struct score* LoadRecordFile(struct score* h);   //从文件中加载学生信息 
	
};
score* Merge_List(score* list1, score* list2) {
		if (list1 == nullptr)
			return list2;
		if (list2 == nullptr)
			return list1;
		if (list1->num < list2->num)
		{
			list1->next = Merge_List(list1->next, list2);
			return list1;
		}
		else
		{
			list2->next = Merge_List(list1, list2->next);
			return list2;
		}
		return list1->num <= list2->num ? list1 : list2;
	}
struct score* record::InsertRecord(struct score* h)
{
	struct score* p1, * p2, * p3;
	p3 = new score;     //创建新的学生结点
	cout << "\n请输入学生学号:";
	cin >> p3->num;
	cout << "\n请输入学生姓名:";
	cin >> p3->name;
	cout << "\n请输入学生的专业:";
	cin >> p3->major;
	cout << "\n请输入学生的班级:";
	cin >> p3->classes;
	cout << "\n请输入学生的性别:";
	cin >> p3->sex;
	cout << "\n请输入学生的年龄:";
	cin >> p3->age;
	p3->next = NULL;   //将要插入结点的指针域置为空

	if (h == NULL)
	{
		h = p3;
		return h;
	}
	p1 = p2 = h;
	while (p1 != NULL && p3->num > p1->num)   //查找结点的学号大于要插入结点的学号的第一个结点    
	{                   //指针p1表示符合条件的结点的指针,指针p2是指针p1的前一个结点的指针
		p2 = p1;
		p1 = p1->next;
	}
	if (p1 == h)  //插入位置为链表头结点前
	{
		p3->next = h;
		h = p3;
		return h;
	}
	else   //插入位置为链表的中间的链表的尾部
	{
		p2->next = p3;
		p3->next = p1;
	}
	studentSum += 1;  //学生人数加1
	return h;    //返回链表的头结点
}
void record::PrintRecord(score* h)
{
	if (h == NULL)
	{
		cout << "\n抱歉,没有任何记录!";
		return;
	}
	cout << "\n学号    \t姓名 \t专业\t班级\t性别\t年龄" << endl;
	while (h)   //输出链表中每个结点的学生信息
	{
		cout << h->num << "\t" << h->name << "\t" << h->major << "\t" << h->classes << "\t" << h->sex << "\t" << h->age << endl;
		h = h->next;
	}
}
struct score* record::DeleteRecord(struct score* h)
{
	struct score* p1, * p2;
	int num;
	if (h == NULL)  //链表为空
	{
		cout << "\n抱歉,没有任何记录!";
		return h;
	}
	p1 = p2 = h;//将链表的头指针赋给指针p1和p2
	cout << "\n请输入要删除记录的学生学号:";
	cin >> num;
	while (p1 != NULL && p1->num != num)//查找结点的学号等于要删除学生学号的第一个结点
	{                     //指针p1表示符合条件的结点的指针,指针p2是指针p1的前一个结点指针
		p2 = p1;
		p1 = p1->next;
	}
	if (p1 == NULL)
	{
		cout << "\n抱歉啊,表中没有该记录哦!";
		return h;
	}
	if (p1->num == num)
	{
		studentSum -= 1;//学生人数减1
		if (p1 == h)  //删除的是头结点
			h = h->next;
		else      //删除的是非头结点
			p2->next = p1->next;
		delete p1;  //释放p1所指向的存储单元
	}
	return h;
}
struct score* record::AUpdateRecord(struct score* h,int x)//修改学生信息
{
	struct score* p1;
	int num;
	if (h == NULL)
	{
		cout << "\n抱歉,没有任何记录!";
		return h;
	}
	p1 = h;
	cout << "\n请输入要修改记录的学生学号:";
	cin >> num;
	while (p1 != NULL && p1->num != num) //查找结点的学号等于要修改学生学号的结点指针
	{
		p1 = p1->next;  //将p1指针移到下一个结点
	}
	if (p1 == NULL)  //没有找到符合要求的结点
	{
		cout << "\n抱歉,表中没有该记录!";
		return h;
	}
	if (p1->num == num)  //找到符合要求的结点,并修改学生的相关信息
	{
		if (x == 1)
		{
			cout << "\n请重新输入学生的姓名:";
			cin >> p1->name;
		}
		if (x == 2)
		{
			cout << "\n请重新输入学生的专业:";
			cin >> p1->major;
		}
		else if (x == 3)
		{
			cout << "\n请重新输入学生的班级:";
			cin >> p1->classes;
		}
		else if (x == 4)
		{
			cout << "\n请重新输入学生的性别:";
			cin >> p1->sex;
		}
		else if (x == 5)
		{
			cout << "\n请重新输入学生的年龄:";
			cin >> p1->age;
		}
	}
	return h;
}
void record::FindRecord(struct score* h, int num)  //根据学生学号查找学生信息
{
	struct score* p1;
	if (h == NULL)
	{
		cout << "\n抱歉,没有任何记录";
		return;
	}
	p1 = h;   //将链表的头结点指针h赋给指针p1
	while (p1 != NULL && p1->num != num) //查找结点的学号等于要查找学生学号的结点指针
	{
		p1 = p1->next;
	}
	if (p1 == NULL)   //没有找到
	{
		cout << "抱歉啊,表中没有该记录的哦!";
		return;
	}
	if (p1->num == num)  //找到并显示信息
	{
		cout << "\n学号    \t姓名 \t专业\t班级\t性别\t年龄" << endl;
		cout << p1->num << "\t" << p1->name << "\t" << p1->major << "\t" << p1->classes << "\t" << p1->sex << "\t" << p1->age  << endl;
	}
}
void record::FindRecord(struct score* h, string name)  //根据学生姓名查找学生信息
{
	struct score* p1;
	if (h == NULL)
	{
		cout << "\n抱歉,没有任何记录!";
		return;
	}
	p1 = h;
	while (p1 != NULL && p1->name != name) //查找结点的姓名等于要查找学生姓名的结点指针
	{
		p1 = p1->next;
	}
	if (p1 == NULL)
	{
		cout << "\n抱歉,表中没有该记录!";
		return;
	}
	if (p1->name == name)
	{
		cout << "\n学号    \t姓名 \t专业\t班级\t性别\t年龄" << endl;
		cout << p1->num << "\t" << p1->name << "\t" << p1->major << "\t" << p1->classes << "\t" << p1->sex << "\t" << p1->age << endl;
	}
}
void record::MajorRecordFind(struct score* h, string major)//按专业查询
{
	struct score* p = h;
	int count = 0;
	if (p == NULL)
	{
		cout << "\n抱歉,没有任何记录!";
		return;
	}
	while (p)
	{
		if (p->major == major) //查找结点的专业等于要查找学生专业的结点指针
		{
			count += 1;
		}
		p = p->next;
	}
	cout << "该专业的人数为:";
	cout << count << endl;
	cout << "改专业的学生信息为:" << endl;
	cout << "\n学号    \t姓名 \t专业\t班级\t性别\t年龄" << endl;
	p = h;
	while (p)
	{
		if (p->major == major)
			cout << p->num << "\t" << p->name << "\t" << p->major << "\t" << p->classes << "\t" << p->sex << "\t" << p->age << endl;
		p = p->next;
	}
}
void record::ClasRecordFind(struct score* h, string classes)//按班级查询
{
	struct score* p = h;
	int count = 0;
	if (p == NULL)
	{
		cout << "\n抱歉,没有任何记录!";
		return;
	}
	while (p)
	{
		if (p->classes == classes) //查找结点的班级等于要查找学生班级的结点指针
		{
			count += 1;
		}
		p = p->next;
	}
	cout << "该班级的人数为:";
	cout << count << endl;
	cout << "该班级的学生信息为:" << endl;
	cout << "\n学号    \t姓名 \t专业\t班级\t性别\t年龄" << endl;
	p = h;
	while (p)
	{
		if (p->classes == classes)
			cout << p->num << "\t" << p->name << "\t" << p->major << "\t" << p->classes << "\t" << p->sex << "\t" << p->age << endl;
		p = p->next;
	}
}
void record::SexRecordFind(struct score* h,string sex)//按性别查询
{
	struct score* p = h;
	int count = 0;
	if (p == NULL)
	{
		cout << "\n抱歉,没有任何记录!";
		return;
	}	
	while (p)
	{
		if ( p->sex == sex) //查找结点的性别等于要查找学生性别的结点指针
		{
			count += 1;
		}
		p = p->next;
	}
	cout << "该性别的人数为:";
	cout << count << endl;
	cout << "该性别的学生信息为:" << endl;
	cout << "\n学号    \t姓名 \t专业\t班级\t性别\t年龄" << endl;
	p = h;
	while (p)
	{
		if (p->sex == sex)
			cout << p->num << "\t" << p->name << "\t" << p->major << "\t" << p->classes << "\t" << p->sex << "\t" << p->age << endl;
		p = p->next;
	}
}
void record::AgeRecordFind(struct score* h, int age)//按年龄查询
{
	struct score* p = h;
	int count = 0;
	if (p == NULL)
	{
		cout << "\n抱歉,没有任何记录!";
		return;
	}
	while (p)
	{
		if (p->age == age) //查找结点的年龄等于要查找学生年龄的结点指针
		{
			count += 1;
		}
		p = p->next;
	}
	cout << "该年龄的人数为:";
	cout << count << endl;
	cout << "改年龄的学生信息为:" << endl;
	cout << "\n学号    \t姓名 \t专业\t班级\t性别\t年龄" << endl;
	p = h;
	while (p)
	{
		if (p->age == age)
			cout << p->num << "\t" << p->name << "\t" << p->major << "\t" << p->classes << "\t" << p->sex << "\t" << p->age << endl;
		p = p->next;
	}
}

void record::SaveRecordFile(struct score* h) //将链表中的数据写入文件
{
	struct score* p;
	ofstream ofile;  //定义输出文件对象
	ofile.open("score.dat", ios::out);  //以定的方式打开文件score.dat,若该文件不存在,则创建score.dat文件
	if (!ofile)
	{
		cout << "\n数据文件打开错误没有将数据写入文件!\n";
		return;
	}
	cout << "\n学号    \t姓名 \t专业\t班级\t性别\t年龄" << endl;
	while (h)
	{
		ofile << endl << h->num << "\t" << h->name << "\t" << "\t" << h->major << "\t" << h->classes << "\t" << h->sex << "\t" << h->age;
		p = h;  //将当前结点的数据信息写入到文件中
		h = h->next;
		delete p;
	}
	ofile.close();
}

struct score* record::LoadRecordFile(struct score* h)
{
	ifstream ifile;  //定义输入文件对象
	ifile.open("score.dat", ios::in);//以读写方式打开文件score.dat
	struct score* p;
	struct score* q = nullptr;
	if (!ifile)
	{
		cout << "\n数据文件不存在,加载不成功!\n";
		return NULL;
	}
	char s[50];
	ifile.getline(s, 50); //读取文件指针当前行数据
	while (!ifile.eof())
	{
		studentSum = studentSum + 1;
		p = new score;
		ifile >> p->num >> p->name >> p->major >> p->classes >> p->sex >> p->age; //
		p->next = NULL;
		if (h == NULL)
		{
			q = h = p;
		}
		else
		{
			q ->next = p;
			q = p;
		}
	}
	ifile.close();
	return h;
}

void SystemMenu(record r)
{
	int choice;
	while (1)
	{
		cout << "\n\t\t欢迎进入学生信息管理系统!";
		cout << "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@";
		cout << "\n\t1、添加学生信息";
		cout << "\n\t2、删除学生信息";
		cout << "\n\t3、修改学生信息";
		cout << "\n\t4、查询学生信息";
		cout << "\n\t5、显示所有学生信息";
		cout << "\n\t6、合并链表";
		cout << "\n\t0、退出系统";
		cout << "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@";
		cout << "\n请根据提示选择操作:";
		cin >> choice;
		switch (choice)
		{
		case 1:           //增加学生信息
			while (1)
			{
				int c;
				cout << "\n*************************************";
				cout << "\n\t1、添加到主表(可存储)";
				cout << "\n\t2、添加到副表(临时表不可存储)";
				cout << "\n\t3、返回上级目录";
				cout << "\n*************************************";
				cout << "\n请根据提示选择操作:";   //显示查询子菜单
				cin >> c;
				if (c ==1)
				{
					head = r.InsertRecord(head);
				}
				if (c == 2)
				{
					head2 = r.InsertRecord(head2);
				}
				if (c == 3)  //退出查询子菜单
					break;
			}		
			break;
		case 2:          //删除学生信息
			head = r.DeleteRecord(head);
			break;
		case 3:    //修改学生信息
			while (1)
			{
				int c;
				cout << "\n*************************************";
				cout << "\n\t1、修改一项,姓名";
				cout << "\n\t2、修改一项,专业";
				cout << "\n\t3、修改一项,班级";
				cout << "\n\t4、修改一项,性别";
				cout << "\n\t5、修改一项,年龄";
				cout << "\n\t6、返回上级目录";
				cout << "\n*************************************";
				cout << "\n请根据提示选择操作:";   //显示查询子菜单
				cin >> c;
				if (c==1||c==2||c==3||c==4||c==5)   //修改一项
				{
					head = r.AUpdateRecord(head,c);				
				}			
			    if (c == 6)  //退出查询子菜单
				  break;
			}
			break;

		case 4:    //查询学生信息        
			while (1)
			{
				int c;
				cout << "\n*************************************";
				cout << "\n\t1、根据学号查询学生信息";
				cout << "\n\t2、根据姓名查询学生信息";
				cout << "\n\t3、根据专业查询学生信息";
				cout << "\n\t4、根据班级查询学生信息";
				cout << "\n\t5、根据性别查询学生信息";
				cout << "\n\t6、根据年龄查询学生信息";
				cout << "\n\t7、返回上级目录";
				cout << "\n*************************************";
				cout << "\n请根据提示选择操作:";   //显示查询子菜单
				cin >> c;
				if (c == 1)   //根据学生学号查询学生信息
				{
					int x;
					cout << "\n请输入需要查询的学生学号:";
					cin >> x;
					r.FindRecord(head, x);
				}
				if (c == 2)   //根据学生姓名查询学生信息
				{
					string name;
					cout << "\n请输入需要查询的学生姓名:";
					cin >> name;
					r.FindRecord(head, name);
				}
				if (c == 3)  //根据专业查询学生信息
				{
					string major;
					cout << "\n请输入需要查询的学生专业:";
					cin >> major;
					r.MajorRecordFind(head, major);
				}
				if (c == 4)  //根据班级查询学生信息
				{
					string classes;
					cout << "\n请输入需要查询的学生班级:";
					cin >> classes;
					r.ClasRecordFind(head, classes);
				}
				if (c == 5)  //根据性别查询学生信息
				{
					string sex;
					cout << "\n请输入需要查询的学生性别:";
					cin >> sex;
					r.SexRecordFind (head, sex);
				}
				if (c == 6)  //根据年龄查询学生信息
				{
					int age;
					cout << "\n请输入需要查询的学生年龄:";
					cin >> age;
					r.AgeRecordFind(head, age);
				}
				if (c == 7)  //退出查询子菜单
					break;
			}
			break;
		case 5:           //输出所有学生成绩信息
			while (1)
			{
				int c;
				cout << "\n*************************************";
				cout << "\n\t1、输出主表学生信息";
				cout << "\n\t2、输出副表学生信息";
				cout << "\n\t3、返回上级目录";
				cout << "\n*************************************";
				cout << "\n请根据提示选择操作:";   //显示查询子菜单
				cin >> c;
				if (c == 1 )  
				{
					r.PrintRecord(head);
				}
				if (c == 2)
				{
					r.PrintRecord(head2);
				}
				if (c ==3)  //退出查询子菜单
					break;
			}
			break;
		case 6:          //
		    head3 = Merge_List(head, head2);//合并a,b
			break;
		}
		if (choice == 0)//退出系统
			break;
	}
}

int main()
{
	head = NULL;
	record r;                   //定义record类的对象r
	head = r.LoadRecordFile(head);  //将文件中的数据读取到链表中
	SystemMenu(r);           //显示系统菜单,并处理用户选择
	r.SaveRecordFile(head);  //将链表中的数据写到文件中
	return 0;
}

任务

采用链式存储完成学生信息的管理。学生信息包括:学号、姓名、专业、班级、性别、年龄等。要求实现学生信息数据的录入、插入、删除、查找、修改、排序、合并等。具体步骤包括:定义链表(任一种)的存储结构、实现相应基本操作、实现学生信息数据的管理;对链表中的学生信息按学号从小到大排序;将两个存储了学生信息的有序链表合并成一个链表。

说明

1、定义学生结构体Student,

成员有:

学号(num【int】),姓名(name【string】),       

专业(major【string】),班级(grade【string】),

性别(sex【string】),年龄(age【int】)。

定义链式存储结构体:

struct score* next;  //next为指向下一结点的指针,struct score* head;  //指向链表头结点的指针,struct score* head2;  //指向链表头结点的指针,struct score* head3;  //指向链表头结点的指针 

2、由于涉及到的函数比较多,这里只对重点函数进行设计说明;

1)插入函数:先判断链表内是否有数据,如果没有,直接将头指针指向此数据,如果有数据,先进行比较大小,在合适的位置上插入数据。

2)删除函数:用P2保存要删除的元素的前一个元素,将p2的后继直接指向要删除元素的下一个元素。

3)合并两个链表,在系统中存在主表和副表,主表数据可以保存,副表不可以,合并链表时采用归并递归,将所有数据存储到主表内。 

效果展示

  • 4
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
数据结构课程设计主要是围绕学生信息管理系统展开,在C语言中使用链表来实现文件的存储和管理。首先,需要设计学生信息数据结构,包括学生的姓名、学号、年龄、性别等基本信息,并在链表中进行存储。在链表的设计中,可以使用单向链表或双向链表来存储学生信息,每个节点代表一个学生,节点中存储该学生的各项信息。 其次,需要设计各种功能来实现学生信息管理,例如添加学生信息、删除学生信息、修改学生信息、查询学生信息等操作。这些功能需要通过各种算法来实现,例如遍历链表、插入节点、删除节点等。 另外,在C语言中使用文件来进行数据的存储和读取。因此,需要设计文件的读功能,将链表中的学生信息存储到文件中,或者从文件中读取学生信息链表中。这涉及到文件操作的知识,包括文件的打开、关闭、入、读取等操作。 除此之外,还需要考虑对学生信息的排序功能,可以按照学号、姓名、年龄等排序来展示学生信息。这需要设计相应的排序算法来实现。 综上所述,数据结构课程设计学生信息管理C语言链表文件主要包括学生信息数据结构设计、链表的实现、文件的读功能设计、各种操作功能的实现以及排序算法的设计。通过这样一个综合的设计,可以帮助学生深入理解数据结构的应用与实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值