桶排序用于海量数据排序的实验。

刚才在JULY的博客上看了对海量数据排序的讲解(http://blog.csdn.net/v_JULY_v/archive/2011/05/28/6451990.aspx),仔细看了几遍,大概理解了使用归并排序的执行过程。于是想知道如果把归并排序替换成其他方法是否可行。仔细想了一下,觉得桶排序可以一试,所写了程序测试了一下。

 

算法的思路是:

第一步。把每个数据最高的k位作为桶编号,创建2^k个桶.然后把每个数据加入到对应的桶中,因为内存有限,把每个桶与一个文件对应,这样可以得到2^k个文件,由于不同桶中的数据大小已经不同,所以只需要分别把每个桶中的数据排好,那么全部数据就是有序的了。

 

第二步。采用类似计数排序的方法分别对每个文件(桶)中的数据进行排序,由于内存有限不能直接使用计数排序,而是用计数排序的简化版。

 

先用一个数组统计每个数字出现的次数

arr[SIZE]={0};

for each d;

  ++arr[d];

 

然后根据数组中每个元素出现的次数由小到大地输出数据。

for each i in arr

       num=arr[i];

       while num!=0

             print i;          //输出结果

             num=num-1;

 

这样就把一个文件中的数据排好了,分析上面的算法会发现它是 稳定 的排序算法。

 

分析数组arr的大小。

因为数据有10^7个,因此,arr中元素的类型至少应是int类型的,占4个字节。由于内存限制为1M 所以数组arr的大小可取到256k=2^18.

也就是说第一步的每个桶最多只能放2^18个不同的数。题目说每个数字最大为10^7=2^24,因此可以将每个数字的第18~23位作为桶编号,可得64个桶。又因为10^7的二进制形式的第18~23位是100110,转成十进制是38, 即最大的数落在编号为38的桶中。因此实际只需39个桶即可。

 

 

---------------------------------------------------------------------------------------

实验结果:

我在vs2010的release版下测试,所使用的数据是用JULY博客中的给出的随机数生成算法生成的。排序所花的总时间为39秒。

 

又在同样的环境下测试了一下JULY博客中的算法执行时间为:

The time needs in memory sort: 22172ms
The time needs in merge sort: 20344ms

这个算法是按两步分别计时的,所以总时间为42秒。

 

可见两个算法执行时间相似。

 

--------------------------------------------------------------------------------

 

源码:

 

----------------------------------------------------------------------------------------------- 

------------------------------------------------------------------------------------------------

对上面的程序改进了一下,上面的算法保存桶中数据时,存的是整个数字,但实际上数据的高位是不用存的,同一个桶中的数据的高位都是相同的,根据桶的编号就可以把数据的高位部分确定出来。于是我对程序做了修改。

原来的桶文件大小约为2.0M,改进以后每个桶的大小为1.68M,执行时间也有所降低。

改进后的算法的执行时间为28秒

又重复做了几次试验,发现所用时间均为33秒。

-------------------------------------

源码:

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值