学生成绩档案管理系统预习日志

学生成绩档案管理系统

实验任务:
1.学生信息录入,包括学号,姓名,专业,四门课程成绩,总分,名次
2.系统可对学生信息浏览增加删除和修改
3.按学生成绩确定名次信息输出,双向冒泡排序,希尔排序,快速排序,堆排序
4.要求可对学生信息查询,更根据学号和姓名进行查找
5.信息修改仅可修改四门课程成绩
6.文件存取学生信息

需求分析:
1.新增学生信息(包括学号姓名专业四门课成绩)
2.浏览学生信息(对学生排序后信息进行浏览)
3.删除学生信息(删除指定学生的信息,可给用户选择检索指定项)
4.查找学生信息(查找复合条件的某条记录)
5.保存学生信息(保存学生成绩档案信息到文本文件中)
6.加载学生信息(登录系统后将磁盘文件中保存的学生成绩信息读取到内存中)

函数需求
查询函数;排序函数;删除函数;修改函数;
输入输出函数;菜单函数;读取与保存数据函数

重要算法分析
堆排序
堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征,使得在当前无序区中选取最大(或最小)关键字的记录变得简单。
堆排序的主要步骤:(1)调整堆;(2)选择、交换、调整。

冒泡排序
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

希尔排序
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2 =1( …

快速排序
首先设定一个分界值,通过该分界值将数组分成左右两部分。
将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。
然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。

源代码

struct student
{
    char name[10];            // 姓名
    char  id[10];        	 // 学号
    float  Ynum;         	 //语文分数
    float  Snum;      		 //数学分数
    float  Enum;       		 //英语分数
    float  Znum;			//政治分数
    float  number;    		//总分
    student* next;
}

class stud
{
    student* p1, * p2, * head;
public:
~stud()                     //析构函数(用来释放空间)
    {

        while (head)
        {
            p1 = head->next;
            delete head;
            head = p1;
        }
    }
    /*
    成员函数
    */
    void output(student* head);             		  //  输出学生成绩
    student* input(student* head);           		 //  增加学生记录
    student* del(student* head, char* p);  			 //  删除记录
    student* find(student* head, char* p, int& n);  // 查找学生记录(可查找多个同名数据)
    student* stat(student* head);       			//排序统计学生总分
    friend void total(student* head);  				 //统计学生总分
    student* insert(student* head);  				 //按学生总分插入记录
    student* clear(student* head);  				 // 删除当前表
    void Inputs(student* p);       					//用于添加数据的子函数
};
void stud::Inputs(student* p)
{
    cout << setw(6) << "姓名" << setw(8) << " 学号"
        << setw(8) << "语文" << setw(8) << "数学"
        << setw(8) << "英语" << endl;

    cin >> p->name >> p->id;
    cin >> p->Ynum;
    while (cin.fail())
    {
        cerr << "您的输入有误,请重新输入" << endl;
        cin.clear();
        cin.sync();
        cin >> p->Ynum;
    }
    cin >> p->Snum;
    while (cin.fail())
    {
        cerr << "您的输入有误,请重新输入" << endl;
        cin.sync();
        cin.clear();
        cin >> p->Snum;
    }
    cin >> p->Enum;
    while (cin.fail())
    {
        cerr << "您的输入有误,请重新输入" << endl;
        cin.clear();
        cin.sync();
        cin >> p->Enum;
    }
    total(p); //计算出总分
}

//输出学生成绩
void stud::output(student* head)
{
    p1 = head;
    while (p1 != NULL)
    {
        cout << setw(6) << p1->name << setw(8)
            << p1->id << setw(8) << p1->Ynum
            << setw(8) << p1->Snum << setw(8)
            << p1->Enum << setw(7) << p1->number << endl;
        p1 = p1->next;
    }
}

//插入学生成绩记录
student* stud::insert(student* head)
{
    p1 = new student;
    Inputs(p1); //调用子函数 增加数据

    p2 = head;
    student* p3 = NULL;
    while ((p2->number < p1->number) && p2->next != NULL)
    {
        p3 = p2;
        p2 = p2->next;
    }
    if (p2->number > p1->number)
    {
        p1->next = p2;
        if (p3 == NULL) //  若当前值是最小的
            return p1;
        p3->next = p1;
        return head;
    }
    else
    {
        p2->next = p1;
        p1->next = NULL;
        return head;
    }


//清空数据
student* stud::clear(student* head)
{
    while (head)
    {
        p1 = head->next;
        delete head;
        head = p1;
    }
    return head;
}

//排序统计函数
student* stud::stat(student* head)
{
    p2 = head;
    p1 = p2->next;

    while (p2->next)  //冒泡法
    {

        if (p2->number > p1->number)
        {         // 把头指针指向当前比较小的节点
            p2->next = p1->next;
            p1->next = head;
            head = p1;

            // 把用于比较的两个指针复位             
  //p2=head;      
            p1 = p2->next;
        }
        else
        {           // 指向下一个节点
            p2 = p2->next;
            p1 = p2->next;
        }//-------------------------------------------

    }
    cout << "当前表以按学生总分排序成功" << endl;
    return head;
}

//删除记录
student* stud::del(student* head, char* p)
{
    p1 = head;
    p2 = NULL;

    while (strcmp(p1->name, p) && p1->next != NULL)
    {
        p2 = p1;
        p1 = p1->next;
    }

    if (!strcmp(p1->name, p))
    {
        if (p1 == head)
            head = p1->next;
        else
            p2->next = p1->next;

        cout << "删除成功,OK" << endl;
        delete p1;
    }
    else
        cout << " 没找到姓名" << p << "的学生.\n"; //结点没找到

    return head;
}

//统计总分
void total(student* p)
{
    p->number = p->Ynum + p->Snum + p->Enum;

}

//查找函数
student* stud::find(student* head, char* p, int& n)
{
    p2 = head;
    while (strcmp(p2->name, p) != 0 && p2->next != NULL)
        p2 = p2->next;
    if (0 == strcmp(p2->name, p))
    {
        cout << setw(6) << p2->name << setw(8)
            << p2->id << setw(8) << p2->Ynum
            << setw(8) << p2->Snum << setw(8)
            << p2->Enum << setw(7) << p2->number << endl;
        n++;
        return p2;
    }
    else
        if (n == 0)
        {
            system("cls");
            cout << "对不起,没有您要查找的学生数据" << endl;
        }
    return NULL;
}

//增加学生记录
student* stud::input(student* head)
{
    p1 = new student;
    p2 = head;
    Inputs(p1); //调用子函数 增加数据 
    if (head == NULL)
    {
        head = p1;
        p1->next = NULL;
        return head;
    }
    while (p2->next != NULL)
        p2 = p2->next;
    p2->next = p1;
    p1->next = NULL;

    return head;
}
int main(void)
{
    stud stus;
    student* head = NULL;
    student* pd; //临时指针, 用于查找函数
    char choice; //用于存放用户的选择项
    char name[10];  //查找,删除记录的 key
    while (1)
    {
        system("cls");
        int n = 0; //计数器,用于在查找时计算有没有同名学生
        cin >> choice;
        fflush(stdin);

        if (choice == '8')  //安全退出
        {
            cout << "谢谢使用,再见" << endl;
            exit(0);
        }//------------------------------------------------
        switch (choice)
        {
        case '1':
            head = stus.input(head);
            break;//------------------------------------------------
        case '2':
            if (head == NULL)
            {
                error();
                break;
            }
            cout << setw(6) << "姓名" << setw(8) << " 学号"
                << setw(8) << "语文" << setw(8) << "数学"
                << setw(8) << "英语" << setw(13) << "总分!!!" << endl;
            stus.output(head);
            _getch();
            break;//------------------------------------------------
        case '3':
            if (head == NULL)
            {
                error();
                break;
            }
            head = stus.stat(head);
            _getch();
            break;//------------------------------------------------

        case '4':
            if (head == NULL)
            {
                error(); //调用函数输出错误信息
                break;
            }
            cout << "请输入想要查找的学生姓名" << " ," << "本系统可以查找重复姓名学生" << endl;
            cin >> name;
            pd = head;
            cout << setw(6) << "姓名" << setw(8) << " 学号"
                << setw(8) << "语文" << setw(8) << "数学"
                << setw(8) << "英语" << setw(13) << "总分!!!" << endl;

            while (pd)   // 循环调用函数, 用于输出多个的同名学生成绩
            {
                pd = stus.find(pd, name, n);
                if (pd == NULL)
                    break;
                pd = pd->next; //指针指向当前以找到的下一个节点,用于查找多个同名学生
            }
            _getch();
            break;//------------------------------------------------
        case '5':
            if (head == NULL)
            {
                error();
                break;
            }
            cout << "请输入想要删除学生姓名" << endl;

            cin >> name;
            head = stus.del(head, name);
            _getch();
            break;//------------------------------------------------

        case '6':
            if (head == NULL)
            {
                error();
                break;
            }
            head = stus.stat(head);
            head = stus.insert(head);
            break;//-----------------------------------------------
        case '7':
            if (head == NULL)
            {
                error();
                break;
            }
            head = stus.clear(head);
            cout << "删除表成功~" << endl;
            _getch();
            break;//-----------------------------------------------
        default:
            cout << " 对不起,您的输入有误,请重新输入。\n";
            _getch();
            break;
        }//------------------------------------------------------
    }
    _getch();
    return 0;
}

结果运行
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值