学生成绩管理系统设计

实现功能:

[问题描述] 请设计一个学生成绩管理系统。学生信息包括学号、姓名、性别、英语、数学、程序设 计、数据结构、总分、名次等内容。请实现如下功能:

(1) 学生信息的录入(并能够检查学号重复者、成绩不超过 100 分检查,计算总分);

(2) 学生信息的查询(可以按照学号和姓名两种方式查询);

(3) 学生信息的修改(一律按照学号对应修改,仅对四门课程成绩修改);

(4) 学生总分的排序(要求稳定排序,有相同分数时按照并列名次处理);

(5) 学生信息的输出;

(6) 退出管理系统 [基本要求]

设计合适的数据结构和算法编写程序完成上述功能,并具有主控菜单,能够按照菜单选 项进行功能操作。

思路 1:

   根据学生管理系统所需要的功能进行函数实现,存储学生的信息用双链表实现。

  学生的信息的录入功能: 我实现的学生信息录入学生总分的排序是一体的,每次录入学生信息后立即进行位置排序,因此用双链表 就非常方便,可以很方便地进行插入,而不需要像数组那样拖拽大量元素,这就是我采用双链表的原因。位置 排序采用的是根据总分排序的内置改进后的顺序插入排序,与修改学生信息的算法一致,会在思路2中详细解 读。

  每次通过新的学生学号信息,在双链表中顺序遍历看是否有重复学号,而选择顺序遍历的原因是由于学号 在双链表中的排序是无序的,有序的只要总分的排序,因此采用顺序查找。

  在学号没问题后才检测分数不超过100,用while循环使检测到后的超100分的成绩修改直到不超过为止。

  学生信息查询功能:

(1):根据学号查询: 由于学号不可重复和学号无序,因此用while循环使指针不断顺序前进。因此顺序查找会在找到后立即输 出,然后break。

(2):根据名字查询: 由于名字可以重复和名字无序,因此用while循环使指针不断前进遍历整个链表,使每个该名字的学生信 息都输出。

学生信息修改功能: 利用指针,找到该学号的学生位置,修改后总分会变,因此需要进行排序。在链表中删除该学生节点,利 用内置的改进顺序插入算法进行插入该节点。

学生总分的排序: 初始化i=1,p指针;p顺序前进,p.总分>p.next.总分,则令p的排名为i且i++。但若p.总分=p.next.总 分,则令p的排名为i即可,使下一个的排名不变,实现并列名次。

学生信息的输出: 利用指针不断前进,在指针不为NULL时输出每个学生的信息。 退出管理系统: 利用return 0退出main函数。

思路 2:

算法思想:

1.改进的顺序插入算法:

顺序比较指针p和录入的节点*stu,但是指针p每次前进,为p=p.next.next,也就是每一次走 两步,比较位置正确就插入,不对就通过比较大小选择后退一步还是p=p.next.next。 这样改进后就比正常的顺序算法快了一倍。

2.修改学生信息中的双链表添加头结点:

需要删除的节点为*stu;

  添加头结点是服务于修改学生信息功能中的删除功能,因为我的思路为每次修改先删 除该节点,然后再插入排序。

没有添加头结点的话需要分多种情况进行讨论,比如删除后链表空,删除的节点位置 不同而删除后链表只有一个元素或多个元素时需要有很多删除条件。因此采用头结点可以有 效解决这个问题,只需要令删除的节点stu的前一个节点指向stu.next,也就是stu.back指 向stu.next;if(stu.next!=NULL){stu.next.back=stu.back;}两个语句即可,减少了大量代码。

采用的方法:

1.存储方法:双链表 利用双链表的特点,一个连接一个。

每次插入,只需要先将前后两元素和自己相互连接即可。删除也只需要把前后两元素 相互连接即可,因此可以很方便地插入和删除,而不用像数组那样拖拽许多元素,使算法的 时间复杂度大大减小。

2.排序方法:顺序查找和改进的顺序插入

顺序查找:

基于查找的选项为学号和名字都是无序的,因此采用顺序查找比较好。一个个地寻 找,找到对应的数据输出。

改进的顺序插入:

从头到尾顺序插入,利用一次走两步进行比较,使时间减少了一倍。

3.功能菜单:while包含switch

Swtich组成功能菜单,break破除本次switch,return 0破除main函数,结束运行。

源码:

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

class datatype
{
public:
    long long int id;
    string sex, name;
    int eng, math, c, shuju, sum, i;
    datatype()
    {
        id = 0;
        eng = math = c = shuju = sum = 0;
        i = 0;
    }
};

class student
{
    public:
        datatype myinfo;
        student* nextstu, *backstu;
        student()
        {
            nextstu = backstu = NULL;
        }
};

class students
{
public:
    student* stus;
    int length;
    students()
    {
        stus = new student;
        length = 0;
    }
};

bool ifture(long long int theid, students thestus);//判断学号重复问题
int nextque(student* &stu, students &thestus);//改进的顺序插入算法(一次两个地寻找,进行顺序插入)
void stuin(students &thestus);//输入学生
void find(string thename, students thestus);//名字查找学生
void find(long long int theid, students thestus);//学号查找学生
void revise(long long int theid, students &thestus);//修改学生信息
void outstus(students thestus);//输出全部学生信息
void que(students &thestus);//内置排序
//改进:
//1.插入算法的一次排序两个,速度为普通的顺序查找的两倍2.头结点,让删除节点快了许多
int main()
{
    students thestus;
    while(1)
    {
        int x;
        cout << "------此为学生管理系统,请输入数字以选择功能操作:" << endl;
        cout << "------功能1:学生信息录入。" << endl;
        cout << "------功能2:学生信息查询。" << endl;
        cout << "------功能3:学生信息修改。" << endl;
        cout << "------功能4,全部学生信息输出。" << endl;
        cout << "------功能5:退出系统。" << endl;
        cin >> x;
    switch(x)
    {
    case 1:
        stuin(thestus);//输入学生
        system("pause");
        system("cls");
        break;
    case 2:
        cout << "-----请选择查找方式:数字1:名字查找,数字2:学号查找。" << endl;
        int x1; cin >> x1;
        if(x1==1)
        {
            string thename;
            cout << "-----请输入名字:" << endl; cin >> thename;
            find(thename,thestus);//名字查找学生
            system("pause");
            system("cls");
            break;
        }
        else if(x1==2)
        {
            long long int theid;
            cout << "-----请输入学号:" << endl; cin >> theid;
            find(theid, thestus);//学号查找学生
            system("pause");
            system("cls");
            break;
        }
        else
        {
            cout << "-----您输入的选项不对,退出。" << endl;
            system("pause");
            system("cls"); 
            break;
        }
    case 3:
        cout << "-----请输入学生的学号:" << endl;
        long long int theid; cin >> theid;
        revise(theid,thestus);//修改学生信息
        system("pause");
        system("cls");
        break;
    case 4:
        outstus(thestus);//输出全部学生信息
        system("pause");
        system("cls");
        break;
    case 5:
        return 0;
    default:
        cout << "你输入的选项错误。" << endl; 
        system("pause");
        system("cls");
        break;
    }
    }
}
void stuin(students &thestus)//输入学生
{
    cout << "请输入录入的学生个数:" << endl;
    int n=0; cin >> n;
    thestus.length = thestus.length + n;
    for (int i = 0; i < n; i++)
    {
        student* stu = new student;
        cout << "请依次输入学生的学号,姓名,性别,英语,数学,程序设计,数据结构的信息或成绩." << endl;
        cout << "性别只有男和女!!!!!" << endl;
        cin >> stu->myinfo.id >> stu->myinfo.name >> stu->myinfo.sex >> stu->myinfo.eng >> stu->myinfo.math >> stu->myinfo.c >> stu->myinfo.shuju;
        if (stu->myinfo.id<=0)
        {
            cout << "学号小于等于0,如果还剩下操作学生次数,请进行下一次输入,学生个数减一。" << endl;
            thestus.length--;
        }
        else
        {
            if (ifture(stu->myinfo.id, thestus))//ture则没有重复学号
            {//某项成绩是否超过一百
                if (stu->myinfo.eng > 100 || stu->myinfo.c > 100 || stu->myinfo.math > 100 || stu->myinfo.shuju > 100)
                {
                    while (stu->myinfo.eng > 100)
                    {
                        cout << "成绩超过100啦,请重新输入英语成绩:" << endl;
                        cin >> stu->myinfo.eng;
                    }
                    while (stu->myinfo.c > 100)
                    {
                        cout << "成绩超过100啦,请重新输入程序设计成绩:" << endl;
                        cin >> stu->myinfo.c;
                    }
                    while (stu->myinfo.math > 100)
                    {
                        cout << "成绩超过100啦,请重新输入数学成绩:" << endl;
                        cin >> stu->myinfo.math;
                    }
                    while (stu->myinfo.shuju > 100)
                    {
                        cout << "成绩超过100啦,请重新输入数据结构成绩:" << endl;
                        cin >> stu->myinfo.shuju;
                    }
                }
                stu->myinfo.sum = stu->myinfo.eng + stu->myinfo.math + stu->myinfo.c + stu->myinfo.shuju;
                nextque(stu, thestus);//改进的顺序插入算法(一次两个地寻找,进行顺序插入)
            }
            else
            {
                cout << "学号重复,如果还剩下操作学生次数,请进行下一次输入,学生个数减一。" << endl;
                thestus.length--;
            }
        }
    }
    //得到名次
    que(thestus);
}

void find(string thename,students thestus)//名字查找学生
{
    student* p = thestus.stus->nextstu; int i = 0;//i为标记
    while(p!=NULL)
    {
     if(thename.compare(p->myinfo.name)==0)//找到该名字
     {
        cout << "学生的学号,姓名,性别,英语,数学,程序设计,数据结构,总分的信息或成绩:" << endl;
        cout << p->myinfo.id << '\t' << p->myinfo.name << '\t' << p->myinfo.sex << '\t' << p->myinfo.eng << '\t' << p->myinfo.math << '\t' << p->myinfo.c << '\t' << p->myinfo.shuju << '\t' << p->myinfo.sum << endl;
        cout << "该学生名次为:" << p->myinfo.i << endl << endl;
        i++;
     }
    p = p->nextstu;
    }
    if (i == 0) { cout << "该名字没有学生。" << endl; }
}

void find(long long int theid, students thestus)//学号查找学生
{
    student* p = thestus.stus->nextstu; int i = 0;
    while (p!=NULL&&p->myinfo.id != theid) { p = p->nextstu; }
    //p==NULL没找到||找到就停
    if (p == NULL) { cout << "该学号没有学生。" << endl; }
    else
    {
        cout << "学生的学号,姓名,性别,英语,数学,程序设计,数据结构,总分的信息或成绩:" << endl;
        cout << p->myinfo.id << '\t' << p->myinfo.name << '\t' << p->myinfo.sex << '\t' << p->myinfo.eng << '\t' << p->myinfo.math << '\t' << p->myinfo.c << '\t' << p->myinfo.shuju << '\t' << p->myinfo.sum << endl;
        cout << "该学生名次为:" << p->myinfo.i << endl;
    }
}

void revise(long long int theid, students &thestus)//修改学生信息
{
    student* p; p = thestus.stus->nextstu;
    while (p!=NULL&&p->myinfo.id != theid) { p = p->nextstu; }//找到该学号位置
    if (p == NULL) { cout << "该学号没有学生。" << endl; }
    else
    {
        cout << "请修改四门成绩,英语,数学,程序设计,数据结构:" << endl;
        cin >> p->myinfo.eng >> p->myinfo.math >> p->myinfo.c >> p->myinfo.shuju;
        if (p->myinfo.eng > 100 || p->myinfo.c > 100 || p->myinfo.math > 100 || p->myinfo.shuju > 100)
        {
            while (p->myinfo.eng > 100)
            {
                cout << "成绩超过100啦,请重新输入英语成绩:" << endl;
                cin >> p->myinfo.eng;
            }
            while (p->myinfo.c > 100)
            {
                cout << "成绩超过100啦,请重新输入程序设计成绩:" << endl;
                cin >> p->myinfo.c;
            }
            while (p->myinfo.math > 100)
            {
                cout << "成绩超过100啦,请重新输入数学成绩:" << endl;
                cin >> p->myinfo.math;
            }
            while (p->myinfo.shuju > 100)
            {
                cout << "成绩超过100啦,请重新输入数据结构成绩:" << endl;
                cin >> p->myinfo.shuju;
            }
        }
        p->myinfo.sum = p->myinfo.eng + p->myinfo.math + p->myinfo.c + p->myinfo.shuju;
        //还要排序,p为修改对象
        //先删点
        p->backstu->nextstu = p->nextstu;
        if (p->nextstu != NULL) { p->nextstu->backstu = p->backstu; }
        //插入该节点
        nextque(p, thestus);//改进的顺序插入算法(一次两个地寻找,进行顺序插入)
    }
}

void outstus(students thestus)//输出全部学生信息
{
    student* p = thestus.stus->nextstu;
    if (p== NULL) { cout << "此时没有学生" << endl; }
    else
    {
        cout << "学生的学号,姓名,性别,英语,数学,程序设计,数据结构,总分的信息或成绩和名次:" << endl;
        while (p != NULL)
        {
            cout << p->myinfo.id << '\t' << p->myinfo.name << '\t' << p->myinfo.sex << '\t' << p->myinfo.eng << '\t' << p->myinfo.math << '\t' << p->myinfo.c << '\t' << p->myinfo.shuju << '\t' << p->myinfo.sum << endl;
            cout << "该学生名次为:" << p->myinfo.i << endl;
            p = p->nextstu;
        }
    }
}

void que(students &thestus)//内置排序
{
    int i = 1; student* p = thestus.stus->nextstu;
    for (int i2 = 0; i2 < thestus.length; i2++)
    {
        if (p->nextstu == NULL || p->myinfo.sum > p->nextstu->myinfo.sum)
        {
            p->myinfo.i = i; i++;
        }
        else { p->myinfo.i = i; }//=
        p = p->nextstu;
    }
}

bool ifture(long long int theid,students thestus)//判断学号重复问题
{//ture则没有重复学号
    student* p = thestus.stus->nextstu;
while(p!=NULL)
{
    if (p->myinfo.id == theid) { return 0; }
    p = p->nextstu;
}
return 1;
}

int nextque(student* &stu,students &thestus)//改进的顺序插入算法(一次两个地寻找,进行顺序插入)
{
    student* p; p = thestus.stus->nextstu;
    stu->backstu = stu->nextstu = NULL;
    if (p == NULL) { thestus.stus->nextstu = stu; stu->backstu = thestus.stus; }//空表
    else//不空
    {
        while(p!=NULL)
        {
            if (stu->myinfo.sum >= p->myinfo.sum) { p->backstu->nextstu = stu; stu->backstu = p->backstu; p->backstu = stu; stu->nextstu = p; return 0; }//stu>=p
            else//stu<p
            {
                if (p->nextstu == NULL) { p->nextstu = stu; stu->backstu = p; return 0; }//p.next=NULL&&p>stu
                else//p.next!=NULL&&p>stu
                {
                    if (p->nextstu->myinfo.sum <= stu->myinfo.sum) { p->nextstu->backstu = stu; stu->nextstu = p->nextstu; p->nextstu = stu; stu->backstu = p; return 0; }//p>stu&&stu>=p.next
                    else//p.next>stu
                    {
                        if (p->nextstu->nextstu == NULL) { p->nextstu->nextstu = stu; stu->backstu = p->nextstu; return 0; }//p.next.next=NULL&&p.next>stu
                        else { p = p->nextstu->nextstu; }//p=p.next.next
                    }
                }
            }
        }
    }
}

  • 8
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、问题描述  学生信息包括:学号、姓名、性别、年龄、班级等信息。  小学生除了包括学生所有信息外,还包括英语、数学和语文成绩。  中学生除了包括小学生所有信息外,还包括地理、历史成绩、家庭住址等信息。 大学生除了包括学生所有信息外,还包括专业、家庭地址、联系方式等信息。  2、功能要求  (1)添加功能:程序能够添加不同学生的记录,提供选择界面供用户选择所要添加的类别,要求学号要唯一,如果添加了重复学号的记录时,则提示数据添加重复并取消添加。  (2)查询功能:可根据学号、姓名等信息对已添加的学生记录进行查询,如果未找到,给出相应的提示信息,如果找到,则显示相应的记录信息。  (3)显示功能:可显示当前系统中所有学生的记录,每条记录占据一行。  (4)编辑功能:可根据查询结果对相应的记录进行修改,修改时注意学号的唯一性。  (5)删除功能:主要实现对已添加的学生记录进行删除。如果当前系统中没有相应的记录,则提示“记录为空!”并返回操作。  (6)统计功能:能根据多种参数进行统计。能统计学生人数、按性别统计、按年龄统计等。  (7)保存功能:可将当前系统中各类记录存入文件中,存入方式任意。  (8)读取功能:可将保存在文件中的信息读入到当前系统中,供用户进行使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值