查找和排序的应用

[问题描述]
 学生信息管理系统
[基本要求]
设计一个学生信息管理系统,学生对象至少要包含:学号、姓名、性别、成绩1、成绩2、总成绩等信息。要求实现以下功能:
1.试选择一种方式存储:基于数组、链表或文件方式
2.总成绩要求自动计算;
3.查询:分别给定学生学号、姓名,能够查找到学生的基本信息(要求至少用两种查找算法实现);
排序:分别按学生的学号、总成绩进行排序(要求至少用两种排序算法实现)。
CODE:

#include <iostream>
#include <cstring>
using namespace std;
//学生数据元素类型
struct student
{
    int num;
    char name[20];
    char sex;
    int grades1,grades2,grade;
};
student stu[1000];
int n;  //学生的数量
//按学号简单插入排序
void numselectsort()
{
    int i,j,k;
    student stu1;
    for(i=0; i<n-1; i++)
    {
        k=i;
        for(j=i+1; j<n; j++)  //前i-1 个元素是序列中最小的元素,并且已经有序
        {
            if(stu[k].num>stu[j].num)  //每次都从i 后面找一个最小的
                k=j;
        }
        if(k!=i)  //将最小的元素放到前i 个后面
        {
            stu1=stu[i];
            stu[i]=stu[k];
            stu[k]=stu1;
        }
    }
}
//按成绩简单插入排序
void gradesselectsort()
{
    int i,j,k;
    student stu1;
    for(i=0; i<n-1; i++)
    {
        k=i;
        for(j=i+1; j<n; j++)
        {
            if(stu[k].grade>stu[j].grade)
                k=j;
        }
        if(k!=i)
        {
            stu1=stu[i];
            stu[i]=stu[k];
            stu[k]=stu1;
        }
    }
}
//按成绩快速排序
int gradesPartition(int low,int high)
{
    stu[n]=stu[low];
    int pivotkey=stu[low].grade;
    while(low<high)
    {
        while(low<high&&stu[high].grade>=pivotkey)  //从后面找一个比枢轴小的
            high--;
        stu[low]=stu[high];  //low为枢轴,已保存,所以先将low赋值
        while(low<high&&stu[low].grade<=pivotkey)  //从前面找一个比枢轴大的
            low++;
        stu[high]=stu[low];  //high的元素已经到前面,可以在high的位置赋值
    }
    stu[low]=stu[n];  //中间为枢轴的位置
    return low;  //最后low和high相同,为中间值的位置,将序列分成了两半
}
void gradesQsort(int low,int high)
{
    if(low<high)
    {
        int pivotioc=gradesPartition(low,high);  //找中间的位置
        gradesQsort(low,pivotioc-1);  //前一半
        gradesQsort(pivotioc+1,high);  //后一半
    }
}
//按学号快速排序
int numPartition(int low,int high)
{
    stu[n]=stu[low];
    int pivotkey=stu[low].num;
    while(low<high)
    {
        while(low<high&&stu[high].num>=pivotkey)
            high--;
        stu[low]=stu[high];
        while(low<high&&stu[low].num<=pivotkey)
            low++;
        stu[high]=stu[low];
    }
    stu[low]=stu[n];
    return low;
}
void numQsort(int low,int high)
{
    if(low<high)
    {
        int pivotioc=numPartition(low,high);
        numQsort(low,pivotioc-1);
        numQsort(pivotioc+1,high);
    }
}
//将排好序的序列输出
void out()
{
    int i;
    for(i=0; i<n; i++)
    {
        cout<<stu[i].num<<" "<<stu[i].name<<" "<<stu[i].grades1<<" "<<stu[i].grades2<<" "<<stu[i].grade<<endl;
    }
}
//顺序查找
int Search(int t)
{
    int i;
    for(i=0; i<n; i++)  //挨个查找
    {
        if(stu[i].num==t)
            return i;
    }
    return -1;
}
//按学号折半查找
int numhalfquery(int sn)
{
    int low=0,high=n-1,mid;
    while(low<=high)
    {
        mid=(low+high)/2;
        if(stu[mid].num==sn)
            return mid;
        else if(stu[mid].num>sn)  //比中间值大说明在后半部分
        {
            high=mid-1;
        }
        else if(stu[mid].num<sn)  //比中间值小说明在前半部分
        {
            low=mid+1;
        }
    }
    return -1;
}
//按姓名顺序查找
int namesearch(char str[20])
{
    int i;
    for(i=0; i<n; i++)
    {
        if(strcmp(str,stu[i].name)==0)
            return i;
    }
    return -1;
}
//按姓名进行字典序排序,简单插入排序
void namesort()
{
    int i,j,k;
    student stu1;
    for(i=0; i<n-1; i++)
    {
        k=i;
        for(j=i+1; j<n; j++)
        {
            if(strcmp(stu[j].name,stu[k].name)<0)
                k=j;
        }
        if(k!=i)
        {
            stu1=stu[i];
            stu[i]=stu[k];
            stu[k]=stu1;
        }
    }
}
//按姓名折半查找
int namehalfquery(char str[20])
{
    int low=0,high=n-1,mid;
    while(low<=high)
    {
        mid=(low+high)/2;
        if(strcmp(stu[mid].name,str)==0)
            return mid;
        else if(strcmp(stu[mid].name,str)>0)
        {
            high=mid-1;
        }
        else if(strcmp(stu[mid].name,str)<0)
        {
            low=mid+1;
        }
    }
    return -1;
}
//哈希查找
void Hash(int t)
{
    student stu1[n];
    memset(stu1,0,sizeof(stu1));
    int i,k;
    for(i=0; i<n; i++)  //需要先将序列再放置一遍
    {
        k=stu[i].num%n;  //有n个元素,可以对n取余。也可找找一个大于n的最小质数
        while(1)
        {
            if(stu1[k].num==0)
            {
                stu1[k]=stu[i];
                break;
            }
            else
            {
                k++;
                k%=n;
            }
        }
    }
    int sum=0;
        k=t%n;
    while(1)
    {
        k=k%n;
        if(stu1[k].num!=t)
        {
            k++;
            sum++;
            if(sum==n)  //因为元素一共有n个,所以查找n次还没找到,说明不存在
            {
                cout<<"查找失败!"<<endl;
                break;
            }
        }
        else
        {
            cout<<stu1[k].num<<" "<<stu1[k].name<<" "<<stu1[k].grades1<<" "<<stu1[k].grades2<<" "<<stu1[k].grade<<endl;
            break;
        }
    }
}
int main()
{
    cout<<"输入学生数量:";
    int i,k,t;
    cin>>n;
    for(i=0; i<n; i++)  //输入学生信息
    {
        cin>>stu[i].num>>stu[i].name>>stu[i].sex>>stu[i].grades1>>stu[i].grades2;
        stu[i].grade=stu[i].grades1+stu[i].grades2;
    }
    cout<<"排序"<<endl;
    cout<<"简单选择排序:"<<endl;
    cout<<"1.按总成绩排序:"<<endl;
    gradesselectsort();
    out();
    cout<<"2.按学号排序:"<<endl;
    numselectsort();
    out();
    cout<<"快速排序:"<<endl;
    cout<<"1.按总成绩排序"<<endl;
    gradesQsort(0,n);
    out();
    cout<<"2.按学号排序:"<<endl;
    numQsort(0,n);
    out();
    cout<<"查询:"<<endl;
    cout<<"按学号查找(-1结束):"<<endl;
    while(1)
    {
        cin>>k;
        if(k==-1)
            break;
        cout<<"1.顺序查找:"<<endl;
        t=Search(k);
        if(t==-1)
            cout<<"查找失败!"<<endl;
        else
            cout<<stu[t].num<<" "<<stu[t].name<<" "<<stu[t].grades1<<" "<<stu[t].grades2<<" "<<stu[t].grade<<endl;
        cout<<"2.折半查找:"<<endl;
        numQsort(0,n);  //折半查找必须是有序的
        t=numhalfquery(k);
        if(t==-1)
            cout<<"查找失败!"<<endl;
        else
            cout<<stu[t].num<<" "<<stu[t].name<<" "<<stu[t].grades1<<" "<<stu[t].grades2<<" "<<stu[t].grade<<endl;
        cout<<"3.哈希查找:"<<endl;
        Hash(k);
    }
    cout<<"按姓名查找(#结束):"<<endl;
    cout<<"按姓名排序:"<<endl;
    namesort();  //先进行排序,因为后面要用到折半查找
    while(1)
    {
        char str[20];
        cin>>str;
        if(str[0]=='#')
            break;
        cout<<"1.顺序查找:"<<endl;
        t=namesearch(str);
        if(t==-1)
            cout<<"查找失败!"<<endl;
        else
            cout<<stu[t].num<<" "<<stu[t].name<<" "<<stu[t].grades1<<" "<<stu[t].grades2<<" "<<stu[t].grade<<endl;
        cout<<"2.折半查找:"<<endl;
        t=namehalfquery(str);
        if(t==-1)
            cout<<"查找失败!"<<endl;
        else
            cout<<stu[t].num<<" "<<stu[t].name<<" "<<stu[t].grades1<<" "<<stu[t].grades2<<" "<<stu[t].grade<<endl;
    }
    return 0;
}

样例输入:

6
10 aa f 50 60
12 bb m 60 40
9 cc m 10 80
11 dd f 80 70
16 ee f 60 70
14 ff m 90 90

样例输出:

排序
简单选择排序:
1.按总成绩排序:
9 cc 10 80 90
12 bb 60 40 100
10 aa 50 60 110
16 ee 60 70 130
11 dd 80 70 150
14 ff 90 90 180
2.按学号排序:
9 cc 10 80 90
10 aa 50 60 110
11 dd 80 70 150
12 bb 60 40 100
14 ff 90 90 180
16 ee 60 70 130
快速排序:
1.按总成绩排序
9 cc 10 80 90
12 bb 60 40 100
10 aa 50 60 110
16 ee 60 70 130
11 dd 80 70 150
14 ff 90 90 180
2.按学号排序:
9 cc 10 80 90
10 aa 50 60 110
11 dd 80 70 150
12 bb 60 40 100
14 ff 90 90 180
16 ee 60 70 130
查询:
按学号查找(-1结束):
16
1.顺序查找:
16 ee 60 70 130
2.折半查找:
16 ee 60 70 130
3.哈希查找:
16 ee 60 70 130
-1
按姓名查找(#结束):
ee
1.顺序查找:
16 ee 60 70 130
2.折半查找:
16 ee 60 70 130
#

猜你喜欢

转载自blog.csdn.net/weixin_44350170/article/details/103518816