学生成绩档案管理系统
实验任务
学生信息录入,信息包括学号、姓名、专业、四门课成绩、总分、名次
系统可对学生信息浏览、增加、删除和修改
按学生成绩名次及信息输入,双向冒泡排序、希尔排序、快速排序、堆排序
要求可对学生信息查询,根据学号或者姓名进行查找
信息删改仅可修改四门课成绩
文件存取学生信息
运行环境:vs2019
系统设计
算法分析
1.双向冒泡排序算法
首先先来了解下冒泡排序算法
冒泡排序算法:
1.比较相邻的元素。如果第一个元素大于第二元素,则交换二者位置。
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。
3.针对所有的元素重复以上的步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
双向冒泡算法是对冒泡排序算法的优化与改善
双向冒泡排序算法:
双向冒泡排序法由两个方向同时进行冒泡,首先由左向右为大元素移动方向,从右向左为小元素移动方向,然后每个元素都依次执行。在第i次移动后,前i个和后i个元素都放到了正确的位置。
代码:
int l = 0,r = this->m_StuNum - 1;
while (l < r)
{
for (int i = l; i < r; i++)
{
Student* temp = NULL;
if (this->m_StuArray[i]->m_toscore > this->m_StuArray[i + 1]->m_toscore)
temp= this->m_StuArray[i];
this->m_StuArray[i] = this->m_StuArray[i + 1];
this->m_StuArray[i + 1] = temp;
}
--r;
for (int j = r; j > l; --j)
{
Student* temp = NULL;
if(this->m_StuArray[j]->m_toscore<this->m_StuArray[j-1]->m_toscore)
temp = this->m_StuArray[j];
this->m_StuArray[j] = this->m_StuArray[j-1];
this->m_StuArray[j-1] = temp;
}
++l;
}
2.希尔排序
原理:
希尔排序是将待排序的数组元素 按下标的一定增量分组 ,分成多个子序列,然后对各个子序列进行直接插入排序算法排序;然后依次缩减增量再进行排序,直到增量为1时,进行最后一次直接插入排序,排序结束。
**增量d 的范围: **1<= d < 待排序数组的长度 (d 需为 int 值)
**增量的取值: **一般的初次取序列(数组)的一半为增量,以后每次减半,直到增量为1。
第一个增量=数组的长度/2,
第二个增量= 第一个增量/2,
第三个增量=第二个增量/2,
以此类推,最后一个增量=1。
3.快速排序
原理:
快速排序的原bai理:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小。
然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
假设要排序的数组是A[1]……A[N],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一躺快速排序。一躺快速排序的算法是:
1、设置两个变量I、J,排序开始的时候I:=1,J:=N;
2、以第一个数组元素作为关键数据,赋值给X,即X:=A[1];
3、从J开始向前搜索,即由后开始向前搜索(J:=J-1),找到第一个小于X的值,两者交换;
4、从I开始向后搜索,即由前开始向后搜索(I:=I+1),找到第一个大于X的值,两者交换;
5、重复第3、4步,直到I=J。
4.堆排序
原理:
堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征,使得在当前无序区中选取最大(或最小)关键字的记录变得简单。
堆排序的主要步骤:(1)调整堆;(2)选择、交换、调整。
附属全代码(还在调试当中):
stu.h
#pragma once
#include<iostream>
#include<string>
#include"student.h"
class Stumessage :public Student
{
public:
Stumessage(int StdId, string name, string major, double toscore, double chscore, double mascore, double enscore, double phscore);
virtual void showInfo();
};
void Stumessage::showInfo()
{
cout << "学号:" << this->m_StdId
<< "\t姓名" << this->m_name
<< "\t专业" << this->m_major
<< "\t语文成绩" << this->m_chscore
<< "\t数学成绩" << this->m_mascore
<< "\t英语成绩" << this->m_enscore
<< "\t物理成绩" << this->m_phscore
<< "\t总成绩" << this->m_toscore << endl;
}
Stumessage::Stumessage(int StdId, string name, string major,double toscore,double chscore,double mascore,double enscore,double phscore)
{
this->m_StdId = StdId;
this->m_name = name;
this->m_major = major;
this->m_toscore = toscore;
this->m_chscore = chscore;
this->m_mascore = mascore;
this->m_enscore = enscore;
this->m_phscore = phscore;
}
Student.h
#pragma once
#include<iostream>
using namespace std;
#include<string>
class Student
{
public:
virtual void showInfo() = 0;
//学号
int m_StdId=0;
//姓名
string m_name="";
//专业
string m_major="";
//总成绩
double m_toscore=0;//总成绩
double m_chscore=0;//语文成绩
double m_mascore=0;//数学成绩
double m_enscore=0;//英语成绩
double m_phscore=0;//物理成绩
};
StudentManage.h
#pragma once
#include<iostream>
using namespace std;
#include<fstream>
#define FILENAME "Student.text"
#include "student.h"
class StudentManage
{
public:
StudentManage();
~StudentManage();
//展示菜单
void Show_Menu();
//退出系统
void exitSystem();
//记录学生人数
int m_StuNum;
//学生数组的指针
Student** m_StuArray;
//增加学生信息
void Add_Stu();
//保存文件
void save();
bool m_FileIsEmpty;//判断文件是否为空
void Show_stu();
//删除职工
void Del_stu();
//判断职工是否存在,如果存在返回职工所在数组中的位置,不存在返回-1
int IsExist(int id);
//修改学生信息
void Mod_stu();
//查找学生
void Find_Stu();
//排序
void Sort_stu();
//获取学生人数,确定需要开辟的空间
int get_StuNum();
//初始化学生
void init_stu();
//清空数据
void Clean_File();
};
StudentManage.cpp
#include "StudentManage.h"
#include "Student.h"
#include"Stu.h"
using namespace std;
StudentManage::StudentManage()
{
//1.文件不存在
ifstream ifs;
ifs.open(FILENAME, ios::in);
if (!ifs.is_open())
{
this->m_StuNum = 0;
this->m_StuArray = NULL;
this->m_FileIsEmpty = true;
ifs.close();
return;
}
//2.文件存在但是为空
char ch;
ifs >> ch;
if (ifs.eof())
{
//文件为空
this->m_StuNum = 0;
this->m_StuArray = NULL;
this->m_FileIsEmpty = true;
ifs.close();
return;
}
//3.文件存在,且有数据,初始化
int num = this->get_StuNum();
this->m_StuNum = num;
this->m_StuArray = new Student * [this->m_StuNum];
this->init_stu();
}
//析构函数
StudentManage::~StudentManage()
{
if (this->m_StuArray != NULL)
{
for (int i = 0; i < this->m_StuNum; i++)
{
if (this->m_StuArray[i] != NULL)
{
delete this->m_StuArray[i];
}
}
delete[] this->m_StuArray;
this->m_StuArray = NULL;
}
}
//展示菜单
void StudentManage::Show_Menu()
{
cout << "***********欢迎使用学生成绩管理系统*************" << endl;
cout << "*****************1.学生信息录入*****************" << endl;
cout << "*****************2.展示学生信息*****************" << endl;
cout << "*****************3.学生成绩排序*****************" << endl;
cout << "*****************4.查找学生信息*****************" << endl;
cout << "*****************5.修改学生信息*****************" << endl;
cout << "*****************6.删除学生信息*****************" << endl;
cout << "*****************7.清空学生档案*****************" << endl;
cout << "*******************8.退出系统*******************" << endl;
cout << "请输入您的选项:" << endl;
}
//退出系统
void StudentManage::exitSystem()
{
cout << "欢迎下次使用!" << endl;
//system("pause");
exit(0);
}
//添加学生信息
void StudentManage::Add_Stu()
{
int addnum = 0;//保存用户输入的数量
cout << "请输入添加学生成绩的数量" << endl;
cin >> addnum;
if (addnum > 0)
{
//添加
//计算添加新空间的
int newsize = this->m_StuNum + addnum;
//开辟新空间
Student** newspace = new Student * [newsize];
//拷贝到新空间
if (this->m_StuArray != NULL)
{
for (int i = 0; i < this->m_StuNum; i++)
{
newspace[i] = this->m_StuArray[i];
}
}
for (int i = 0; i < addnum; i++)
{
int StdId = 0;
string name="";
string major="";
double toscore=0;
double chscore=0;
double mascore=0;
double enscore=0;
double phscore=0;
cout << "请输入第" << i + 1 << "个学生的学号" << endl;
cin >> StdId;
cout << "请输入第" << i + 1 << "个学生的姓名" << endl;
cin >> name;
cout << "请输入第" << i + 1 << "个学生的专业" << endl;
cin >> major;
cout << "请输入第" << i + 1 << "个学生的语文成绩" << endl;
cin >> chscore;
cout << "请输入第" << i + 1 << "个学生的数学成绩" << endl;
cin >> mascore;
cout << "请输入第" << i + 1 << "个学生的英语成绩" << endl;
cin >> enscore;
cout << "请输入第" << i + 1 << "个学生的物理成绩" << endl;
cin >> phscore;
toscore = chscore + mascore + enscore + phscore;
Student* stu = NULL;
stu = new Stumessage(StdId, name, major,toscore,chscore,mascore,enscore,phscore);
newspace[this->m_StuNum + i] = stu;
}
delete[] this->m_StuArray;
this->m_StuArray = newspace;
this->m_StuNum = newsize;
cout << "成功添加" << endl;
this->save();//保存数据到文件中
this->m_FileIsEmpty = false;
}
else
{
cout << "输入有误请重新输入";
}
system("pause");
system("cls");
}
//将学生信息保存在文件当中
void StudentManage::save()
{
ofstream ofs;
ofs.open(FILENAME, ios::out); //写文件
for (int i = 0; i < this->m_StuNum; i++)
{
ofs << this->m_StuArray[i]->m_StdId << " "
<< this->m_StuArray[i]->m_name << " "
<< this->m_StuArray[i]->m_major << " "
<< this->m_StuArray[i]->m_chscore << " "
<< this->m_StuArray[i]->m_mascore << " "
<< this->m_StuArray[i]->m_enscore << " "
<< this->m_StuArray[i]->m_phscore << " "
<< this->m_StuArray[i]->m_toscore << " " << endl;
}
ofs.close();
}
//展示学生信息
void StudentManage::Show_stu()
{
if (this->m_FileIsEmpty)
{
cout << "文件不存在或者记录为空" << endl;
}
else
{
for (int i = 0; i < m_StuNum; i++)
{
cout << "名次:" << i+1 << " ";
this->m_StuArray[i]->showInfo();
}
}
system("pause");
system("cls");
}
//删除学生信息
void StudentManage::Del_stu()
{
if (this->m_FileIsEmpty)
{
cout << "文件不存在或记录为空!" << endl;
}
else
{
//按照学生学号进行删除
cout << "输入想要删除的学生学号" << endl;
int id = 0;
cin >> id;
int index = this->IsExist(id);
if (index != -1)
{
for (int i = index; i < m_StuNum - 1; i++)
{
this->m_StuArray[i] = this->m_StuArray[i + 1];
}
this->m_StuNum--;//更新数组中的人员
this->save();
cout << "删除成功" << endl;
}
else {
cout << "删除失败" << endl;
}
//说明职工存在
}
system("pause");
system("cls");
}
//通过学号查找学生是否存在,如果存在则返回学生所在数组的位置,若不存在则返回-1
int StudentManage::IsExist(int id)
{
int index = -1;
for (int i = 0; i < this->m_StuNum; i++)
{
if (this->m_StuArray[i]->m_StdId == id)//找到员工
{
index = i;//返回数组的位置
break;
}
}
return index;
}
//修改学生信息
void StudentManage::Mod_stu()
{
if (this->m_FileIsEmpty)
{
cout << "文件不存在或者为空" << endl;
}
else {
cout << "请输入想要修改成绩的学生学号" << endl;
int id=0;
cin >> id;
int ret = this->IsExist(id);
if (ret != -1) {
//查找学生学号是否存在
delete this->m_StuArray[ret];
int StdId = 0;
string name = "";
string major = "";
double toscore = 0;
double chscore = 0;
double mascore = 0;
double enscore = 0;
double phscore = 0;
cout << "查找的:" << id << "学生的学号,请输入新的学号" << endl;
cin >> StdId;
cout << "输入学生的姓名"<< endl;
cin >> name;
cout << "输入学生的专业" << endl;
cin >> major;
cout << "输入学生的语文成绩" << endl;
cin >> chscore;
cout << "输入学生的数学成绩" << endl;
cin >> mascore;
cout << "输入学生的英语成绩" << endl;
cin >> enscore;
cout << "输入学生的物理成绩" << endl;
cin >> phscore;
Student*stu = NULL;
toscore = chscore + mascore + enscore + phscore;
stu = new Stumessage(StdId, name, major, toscore, chscore, mascore, enscore, phscore);
this->m_StuArray[ret] = stu;
cout << "修改成功" << endl;
this->save();
}
else
{
cout << "修改失败,查无此人" << endl;
}
}
system("pause");
system("cls");
}
//通过两种方式查找学生信息
void StudentManage::Find_Stu()
{
if (this->m_FileIsEmpty)
{
cout << "文件不存在或记录为空" << endl;
}
else
{
cout << "请输入查找方式" << endl;
cout << "1.按照学生的学号查找" << endl;
cout << "2.按照学生的姓名查找" << endl;
int select = 0;
cin >> select;
if (select == 1)
{
int id;
cout << "请输入查找的学生的学号" << endl;
cin >> id;
int ret = IsExist(id);
if (ret != -1)
{
cout << "查找成功,该学生的成绩如下:" << endl;
this->m_StuArray[ret]->showInfo();
}
else
{
cout << "查无此人" << endl;
}
}
else if (select == 2)
{
string name;
cout << "请输入查找的学生的姓名" << endl;
cin >> name;
bool flag = false;
for (int i = 0; i < m_StuNum; i++)
{
if (m_StuArray[i]->m_name == name)
{
cout << "查找成功,学号为"
<< m_StuArray[i]->m_StdId
<< "号的信息如下" << endl;
flag = true;
this->m_StuArray[i]->showInfo();
}
}
if (flag = false)
{
cout << "查找失败,查无此人" << endl;
}
}
else
{
cout << "输入有误,请重新输入" << endl;
}
}
system("pause");
system("cls");
}
//排序
void StudentManage::Sort_stu()
{
if (this->m_FileIsEmpty)
{
cout << "文件不存在或者记录为空" << endl;
system("pause");
system("cls");
}
else
{
cout << "请选择排序方式" << endl;
cout << "1.双向冒泡排序" << endl;
cout << "2.希尔排序" << endl;
cout << "3.快速排序" << endl;
cout << "4.堆排序" << endl;
int ch = 0;
cin >> ch;
if (ch == 1)//双向冒泡排序
{
int l = 0,r = this->m_StuNum - 1;
while (l < r)
{
for (int i = l; i < r; i++)
{
Student* temp = NULL;
if (this->m_StuArray[i]->m_toscore > this->m_StuArray[i + 1]->m_toscore)
{
temp = this->m_StuArray[i];
this->m_StuArray[i] = this->m_StuArray[i + 1];
this->m_StuArray[i + 1] = temp;
}
}
--r;
for (int j = r; j > l; --j)
{
if (this->m_StuArray[j]->m_toscore < this->m_StuArray[j - 1]->m_toscore)
{
Student* temp = NULL;
temp = this->m_StuArray[j];
this->m_StuArray[j] = this->m_StuArray[j - 1];
this->m_StuArray[j - 1] = temp;
}
}
++l;
}
cout << "排序成功!排序后的结果为:" << endl;
this->Show_stu();
}
else if (ch == 2)//2.希尔排序
{
double insertNum = 0;
unsigned gap = m_StuNum / 2 + 1;
while (gap)
{
for (unsigned i = gap; i < m_StuNum; ++i)
{
insertNum = m_StuArray[i]->m_toscore;
unsigned j = i;
while (j >= gap && insertNum < m_StuArray[j - gap]->m_toscore)
{
this->m_StuArray[j] = this->m_StuArray[j - gap];
j -= gap;
}
m_StuArray[j] = m_StuArray[i];
}
gap = gap / m_StuNum;
}
cout << "排序成功!排序后的结果为:" << endl;
this->Show_stu();
}
else if (ch == 3)//快速排序
{
int start=0, last=m_StuNum/4-1;
int i = start;
int j = last;
double temp = m_StuArray[i]->m_toscore;
if (i < j)
{
while (i < j)
{
while (i < j && m_StuArray[j]->m_toscore >= temp)
j--;
if (i < j)
{
m_StuArray[i] = m_StuArray[j];
i++;
}
while (i<j && temp>m_StuArray[i]->m_toscore)
i++;
if (i < j)
{
m_StuArray[j] = m_StuArray[i];
j--;
}
}
}
cout << "排序成功!" << endl;
this->Show_stu();
}
//堆排序
else if (ch == 4)
{
for (int i = 0; i < m_StuNum; i++)
{
int minscore = i;
for (int j = i + 1; j < this->m_StuNum; j++)
{
if (this->m_StuArray[minscore]->m_toscore < this->m_StuArray[j]->m_toscore)
minscore = j;
}
if (i != minscore)
{
Student* temp = NULL;
temp = this->m_StuArray[i];
this->m_StuArray[i] = this->m_StuArray[minscore];
this->m_StuArray[minscore] = temp;
}
}
cout << "排序成功!" << endl;
this->Show_stu();
}
}
system("pause");
system("cls");
}
int StudentManage::get_StuNum()
{
ifstream ifs;
ifs.open(FILENAME, ios::in);
int num = 0;
int StdId = 0;
//姓名
string name = "";
//专业
string major = "";
//总成绩
double toscore = 0;//总成绩
double chscore = 0;//语文成绩
double mascore = 0;//数学成绩
double enscore = 0;//英语成绩
double phscore = 0;//物理成绩
while (ifs >> StdId && ifs >> name && ifs >> major && ifs >> toscore && ifs >> chscore && ifs >> mascore && ifs >> enscore && ifs >> phscore)
{
//统计人数
num++;
}
return num;
ifs.close();
}
void StudentManage::init_stu()
{
ifstream ifs;
ifs.open(FILENAME, ios::in);
int StdId = 0;
//姓名
string name = "";
//专业
string major = "";
//总成绩
double toscore = 0;//总成绩
double chscore = 0;//语文成绩
double mascore = 0;//数学成绩
double enscore = 0;//英语成绩
double phscore = 0;//物理成绩
int index = 0;
while (ifs >> StdId && ifs >> name && ifs >> major&&ifs>>toscore&&ifs>>chscore&&ifs>>mascore&&ifs>>enscore&&ifs>>phscore)
{
Student* stu2 = NULL;
toscore = chscore + mascore + enscore + phscore;
stu2 = new Stumessage(StdId, name, major, toscore, chscore, mascore, enscore, phscore);
this->m_StuArray[index] = stu2;
index++;
}
ifs.close();
}
void StudentManage::Clean_File()
{
cout << "是否删除清空" << endl;
cout << "1.是" << endl;
cout << "2.否" << endl;
int ch = 0;
cin >> ch;
if (ch == 1)
{
//进行清空操作
ofstream ofs(FILENAME, ios::trunc);//删除文件后重新创建
ofs.close();
if (this->m_StuArray != NULL)
{
for (int i = 0; i < m_StuNum; i++)
{
delete this->m_StuArray[i];
this->m_StuArray[i] = NULL;
}
//删除堆区
delete[] this->m_StuArray;
this->m_StuArray = NULL;
this->m_StuNum = 0;
this->m_FileIsEmpty = true;
}
cout << "删除成功" << endl;
}
system("pause");
system("cls");
}
学生成绩档案管理系统.cpp
#include<iostream>
#include"StudentManage.h"
using namespace std;
int main()
{
while (true)
{
StudentManage stu;
stu.Show_Menu();
int ch;
cin >> ch;
switch (ch)
{
case 1:
stu.Add_Stu();//学生信息录入
break;
case 2:
stu.Show_stu();//展示学生信息
break;
case 3:
stu.Sort_stu();//排序
break;
case 4:
stu.Find_Stu();//查找学生信息
break;
case 5:
stu.Mod_stu(); //修改学生信息
break;
case 6://清空文件
stu.Del_stu();
break;
case 7:
stu.Clean_File();
break;
case 8://退出系统
stu.exitSystem();
break;
default:
break;
}
}
}