【继续思考】排序算法——基数排序与桶排序

基数排序可以用于较大数的排序,克服了计数排序的这一缺点。

基数排序思想并不复杂,通常我们排序有两种思路,从高位到低位,或者,从低位到高位。比如比较年月日,我们通常会先比较年份,年份相等时,再比较月份,月份相等时,再比较日期。

下面这段话,我觉得写得很简单通俗,帮助了我理解(来源http://blog.csdn.net/hazir/article/details/6396194)

计数排序的缺点很明显,需要额外的空间C来作为计数数组,虽然时间复杂度为O(n+k),但当输入序列里元素取值很大的时侯,如k=O(n2),时,此时时间复杂度已经达到n2数量级了,空间的消耗也是让人无法承受的。这里介绍一种另一种线性排序算法——基数排序,可以应对数值很大的情况。

基数排序,即一个数位一个数位地进行排序,平常生活中我们经常使用的一种算法思想:如要对一个日期进行排序,日期中由年、月、日组成的,对于这个问题,我们经常使用的是先比较年份,如果相同再比较月份,如果还相同就比较日。

同理,我们比较一组数,也可以采取这种思想。例如我们使用这种思想对下面四个数进行排序:123、312、245、531,第一次按百位排序:123、245、312、531;第二次按十位排序:312、123、531、245;第三次按个位数排序:531、312、123、245。咦?为什么最后排出来的结果并不是预期的那样?原因是我们从高位开始排序,已经差不多整体有序之后,再到低位时,又全部被打乱了。如果我们之后这样做就不会乱了:高位相同的数,再将它们的低位进行排序….不过这个实现一起比较困难一些。

这里,我们换成从最低有效位到最高有效位进行排序,那么还是上面那个例子:

   个位 =>  十位 =>  百位

   531      312      123

   312      123      245

   123      531      312

   245      245      531

可以看到结果正确。通俗地讲,之所以先排低位再排高位,是因为越是后排的数位,其对结果次序的影响越大,很显然是高位比低位对数的大小影响大!

所以,其实思想不复杂,下面是还没实现的代码,今天晚上有点晚了,脑子不是很清醒,先放在这里,明天再继续写:(看算法思想,请忽略下面的代码)

//基数排序
int main()
{
	int a[20] = {329,457,1234,23,56,6,9,13546,7,164,123,124,224,223,456,457,156,124567,987,20};
	int b[20] = {0};
	int temp[10] = {0};//,每一位的数不会超过9

	int max = 0;

	for (int i = 0; i < 20; i++)//找出位数最多的数
	{
		int num = a[i];
		int res = 1;
		while (num / 10)
		{
			num = num / 10;
			res++;
		}		
		if (res>max)
			max = res;
	}

	for (int i = 0; i < max; i++)//控制从低位到高位开始比较
	{
		for (int j = 0; j < 20; j++)
		{
			int num = a[j];
			int wei = num % 10;
			


		}
	}

	return 0;
}

觉得自己好像已经理解基数排序了,今天发现自己似乎并没有理解得很透。看了一篇文章,觉得写得很好

http://www.cnblogs.com/Braveliu/archive/2013/01/21/2870201.html

其实基数排序,可以从最低位开始排,也可以从最高位开始排。最高位开始排的这种思想,其实感觉有点类似与桶排序

二、桶排序思想

桶排序思想也不是很复杂(其实我一直觉得理解堆排序是最复杂的)

桶排序要求数组里的元素服从均匀分布(因此使用的范围不是非常广)。先按照某种规则,将待排序数组元素放入桶中。如,0-1000的数,用100个桶来装,每个桶可以装10个。这样0-10,10-20,20-30分出来,可以将待排序数装入其中,再对每个桶的元素进行排序。暂时不写代码了,因此目前对链表和指针的操作还不是很熟练,过段时间过来写代码的实现部分。(算法导论第三版,桶排序很好理解)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值