Counting Sort 计数排序算法在学生管理系统排序的应用例子

来源:互联网 发布:中国海警3501数据参数 编辑:程序博客网 时间:2024/05/29 19:07

这个算法主要用在关键数字(key number)小的时候,按照关键数字排序的效率是非常高的。

比如我们有6个教室的学生需要按教室号排序,如下是学生的信息数据结构:

struct StudentData {string name;int classNum;StudentData():name("No Name"), classNum(0){}StudentData(int num, string na):classNum(num), name(na){}void print();};
void StudentData::print(){ cout<<classNum<<"\t\t"<<name<<endl;}



需要的空间就是关键数字的最大值的空间,比如关键字最大是6,那么就需要6+1个空间。如果是从后面开始填表,那么就只需要6个空间。
思路:
主要需要三个步骤:
1 新建一个关键数字大小+1的vector vi,并以关键字出现的次数为vi的下标,计算其出现的总次数
2 把前面教室号出现的总次数加起来就是本教室号开始填表的位置
3 根据教室号开始填表,每填写一个学生信息,那么就需要把填表下标+1.

三部曲,就只需要三个循环,如C++程序:

class Solution {public:void countingSort(vector<StudentData> &vstu){vector<int> vi(MAXCLASS+1);//三部曲1:计算所有classNum出现的次数for(auto x:vstu){vi[x.classNum]++;}//三部曲2:计算需要摆放数据的初始位置for (int i = 1; i < vi.size(); i++){vi[i] += vi[i-1];}vector<StudentData> tempVstu(vstu.size());for(auto x:vstu){//三部曲3: x.classNum是student的教室号,前面的教室学生填写完毕,就开始填写这个教室的学生//所以这个教室号在其他教室学生信息填写完毕之后才填写,所以开始位置是前面学生总和//x.classNum-1代表前面所有教室号的学生总数,也是本教室号开始填写学生信息的开始号码//用这个号码在vi中抽去前面填写好的下标//++代表填了一个学生信息,那么后面填写的学生号需要+1.tempVstu[vi[x.classNum-1]++] = x;}//复制回原来数列vstu = tempVstu;}};


下面是主程序:

int main(){vector<StudentData> vstu;vstu.push_back(StudentData(1,"s1"));vstu.push_back(StudentData(2,"s2"));vstu.push_back(StudentData(3,"s3"));vstu.push_back(StudentData(5,"s5"));vstu.push_back(StudentData(4,"s4"));vstu.push_back(StudentData(3,"s33"));vstu.push_back(StudentData(6,"s6"));vstu.push_back(StudentData(2,"s22"));vstu.push_back(StudentData(5,"s55"));vstu.push_back(StudentData(2,"s222"));vstu.push_back(StudentData(6,"s66"));vstu.push_back(StudentData(4,"s44"));cout<<"Before sort:\nclass number\tstudent name\n";for (auto x:vstu)x.print();cout<<endl;Solution solu;solu.countingSort(vstu);cout<<"After sort:\nclass number\tstudent name\n";for (auto x:vstu)x.print();system("pause");return 0;}


运行结果:

原创粉丝点击