实验五——查找和排序的应用

实验内容

[问题描述]

学生信息管理系统

[基本要求]

设计一个学生信息管理系统,学生对象至少要包含:学号、姓名、性别、成绩1、成绩2、总成绩等信息。要求实现以下功能:

1.试选择一种方式存储:基于数组、链表或文件方式

2.总成绩要求自动计算;

3.查询:分别给定学生学号、姓名,能够查找到学生的基本信息(要求至少用两种查找算法实现);

排序:分别按学生的学号、总成绩进行排序(要求至少用两种排序算法实现)。

[测试数据]

  由学生依据软件工程的测试技术自己确定。

主要思想

建立结构体,从文件中读入数据到结构体中。设立两个函数,功能分别为输出菜单和全部信息,以备重复调用。对学号使用冒泡排序,即依次比较相邻的两个数,将小数放在前面,大数放在后面,对总成绩使用堆排序,先建初堆,再调整堆,最后进行堆排序。按姓名查找时使用顺序查找,按学号查找时使用折半查找,需要注意的是,折半查找学号要保证学号是有序的。

代码实现

#include<stdio.h>//实验五
#include<stdlib.h>
#include<string.h>
#include<iostream>
using namespace std;
typedef struct{
    char num[4];
    char name[10];
    char sex[4];
    int score1;
    int score2;
    int sum;
}StuType;//学生信息结构体
typedef struct{
    StuType S[15];
    int stunum;
}Student;//学生信息表
void menu(){//菜单
    cout<<"***************学生信息管理系统***************"<<endl;
    cout<<"               1、根据学号查找学生"<<endl;
    cout<<"               2、根据姓名查找学生"<<endl;
    cout<<"               3、根据学号排序输出"<<endl;
    cout<<"               4、根据总成绩排序输出"<<endl;
    cout<<"               5、退出"<<endl;
    cout<<"**********************************************"<<endl;
    cout<<"请选择...\n";
}
void Allprint(Student &Stu){//打印全部信息
    printf("学号\t姓名\t性别\t成绩1\t成绩2\t总成绩\n");
    for (int i =1;i<=Stu.stunum;i++)
	{
        printf("%s\t%s\t%s\t%d\t%d\t%d\n",Stu.S[i].num,Stu.S[i].name,Stu.S[i].sex,Stu.S[i].score1,
         Stu.S[i].score2,Stu.S[i].sum);
	}
}
void Read(Student &Stu){//从文件中读入信息到结构体
    FILE *fp=fopen("C:\\Users\\chenxianning\\Documents\\c c++\\数据结构课设\\students.txt","rb");
    if(fp==NULL){//判断文件是否可以打开
        cout<<"can not open the file"<<endl;
        exit(0);
    }
    for(int i=1;;i++){
        int n=fscanf(fp,"%s%s%s%d%d",Stu.S[i].num,Stu.S[i].name,Stu.S[i].sex,&Stu.S[i].score1,&Stu.S[i].score2);
        Stu.S[i].sum=Stu.S[i].score1+Stu.S[i].score2;//计算总成绩
        if(n==-1){//文件读入结束
            Stu.stunum=i-1;
            fclose(fp);
            break;
        }
    }
    fclose(fp);//关闭文件
}
void NumSort(Student &Stu){ //冒泡排序
    int m=Stu.stunum;
    int flag=1;//标记某一趟排序是否发生交换
    int j;
    StuType t;
    while((m>0)&&(flag==1)){//flag置为0,如果本次没有发生交换,就不会执行下一趟
        flag=0;
        for(j=1;j<m;j++)
            if(strcmp(Stu.S[j].num,Stu.S[j+1].num)>0)
            {
                flag=1;
                t=Stu.S[j];//交换前后记录
                Stu.S[j]=Stu.S[j+1];
                Stu.S[j+1]=t;
            }
        --m;
    }
}
void HeapAdjust(Student &Stu,int s,int m){//调整堆
    StuType rc=Stu.S[s];
    for(int j=2*s;j<=m;j*=2){//沿key值较大的孩子结点向下筛选
        if(j<m&&Stu.S[j].sum<Stu.S[j+1].sum)++j;//j为key值较大的记录的下标
        if(rc.sum>=Stu.S[j].sum)break;//rc应插在位置s上
        Stu.S[s]=Stu.S[j];
        s=j;
    }
    Stu.S[s]=rc;//插入
}
void CreatHeap(Student &Stu){//建初堆
    int n=Stu.stunum;//建成大根堆
    for(int i=n/2;i>0;--i)
        HeapAdjust(Stu,i,n);
}
void SumSort(Student &Stu){//堆排序
    CreatHeap(Stu);
    StuType t;
    for(int i=Stu.stunum;i>1;--i){
        t=Stu.S[1];//把堆顶元素和未经排序子序列中最后一个元素做交换
        Stu.S[1]=Stu.S[i];
        Stu.S[i]=t;
        HeapAdjust(Stu,1,i-1);
    }
    Allprint(Stu);
}
void NameSearch(Student &Stu){//顺序查找
    cout<<"请输入该学生的姓名:";
    char key[4];
    cin>>key;
    int nn,i;
    strcpy(Stu.S[0].name,key);//哨兵
    for(i=Stu.stunum;;--i)//从后往前找
        if(strcmp(Stu.S[i].name,Stu.S[0].name)==0)
           {
                nn=i;
                break;
           }
    nn=i;
    if(i==0)
    {
         cout<<"查无此人!"<<endl;
         return;
    }
    cout<<"查询成功!"<<endl;
    cout<<"学号:"<<Stu.S[nn].num<<"  姓名:"<<Stu.S[nn].name<<"  性别:"<<Stu.S[nn].sex<<"  成绩1:"<<Stu.S[nn].score1
    <<"  成绩2:"<<Stu.S[nn].score2<<"  总成绩:"<<Stu.S[nn].sum<<endl;
}
void NumSearch(Student &Stu){//折半查找
    NumSort(Stu);
    cout<<"请输入该学生的学号:";
    char key[4];
    cin>>key;
    int nn=0;
    int low,high,mid;
    low=1;//置查找区间初值
    high=Stu.stunum;
    while(low<=high)
    {
        mid=(high+low)/2;
        if(strcmp(key,Stu.S[mid].num)==0)//找到待查元素
        {
            nn=mid;
            break;
        }
        else if(strcmp(key,Stu.S[mid].num)<0)//继续在前一子表进行查找
            high=mid-1;
        else//继续在后一子表进行查找
            low=mid+1;
    }
    cout<<"查询成功!"<<endl;
    cout<<"学号:"<<Stu.S[nn].num<<"  姓名:"<<Stu.S[nn].name<<"  性别:"<<Stu.S[nn].sex<<"  成绩1:"<<Stu.S[nn].score1
    <<"  成绩2:"<<Stu.S[nn].score2<<"  总成绩:"<<Stu.S[nn].sum<<endl;
    return;
}
int main(){
    Student Stu;
    Read(Stu);
    int m;
    while(m!=5){
        menu();
        cin>>m;
    switch(m){
        case 1:
            NumSearch(Stu);
            break;
        case 2:
            NameSearch(Stu);
            break;
        case 3:
            NumSort(Stu);
            Allprint(Stu);
            break;
        case 4:
            SumSort(Stu);
            break;
        case 5:
            cout<<"感谢您的使用!"<<endl;
            return 0;
        default:
            cout<<"没有该选项!"<<endl;
            break;
    }
    system("pause");
    system("cls");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/DEAR_CXN/article/details/86583764
今日推荐