[问题描述]
学生信息管理系统
[基本要求]
设计一个学生信息管理系统,学生对象至少要包含:学号、姓名、性别、成绩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
#