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

这个算法主要用在关键数字(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;
}


运行结果:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值