学生成绩管理系统设计

时间:2025-02-19 08:09:56

实现功能:

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

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

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

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

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

(5) 学生信息的输出;

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

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

思路 1:

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

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

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

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

  学生信息查询功能:

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

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

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

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

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

思路 2:

算法思想:

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

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

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

需要删除的节点为*stu;

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

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

采用的方法:

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;
     =  + n;
    for (int i = 0; i < n; i++)
    {
        student* stu = new student;
        cout << "请依次输入学生的学号,姓名,性别,英语,数学,程序设计,数据结构的信息或成绩." << endl;
        cout << "性别只有男和女!!!!!" << endl;
        cin >> stu-> >> stu-> >> stu-> >> stu-> >> stu-> >> stu-> >> stu->;
        if (stu-><=0)
        {
            cout << "学号小于等于0,如果还剩下操作学生次数,请进行下一次输入,学生个数减一。" << endl;
            --;
        }
        else
        {
            if (ifture(stu->, thestus))//ture则没有重复学号
            {//某项成绩是否超过一百
                if (stu-> > 100 || stu-> > 100 || stu-> > 100 || stu-> > 100)
                {
                    while (stu-> > 100)
                    {
                        cout << "成绩超过100啦,请重新输入英语成绩:" << endl;
                        cin >> stu->;
                    }
                    while (stu-> > 100)
                    {
                        cout << "成绩超过100啦,请重新输入程序设计成绩:" << endl;
                        cin >> stu->;
                    }
                    while (stu-> > 100)
                    {
                        cout << "成绩超过100啦,请重新输入数学成绩:" << endl;
                        cin >> stu->;
                    }
                    while (stu-> > 100)
                    {
                        cout << "成绩超过100啦,请重新输入数据结构成绩:" << endl;
                        cin >> stu->;
                    }
                }
                stu-> = stu-> + stu-> + stu-> + stu->;
                nextque(stu, thestus);//改进的顺序插入算法(一次两个地寻找,进行顺序插入)
            }
            else
            {
                cout << "学号重复,如果还剩下操作学生次数,请进行下一次输入,学生个数减一。" << endl;
                --;
            }
        }
    }
    //得到名次
    que(thestus);
}

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

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

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

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

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

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

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