编程珠玑1

      编程珠玑第一章中提出问题,需要对包含1到N之间n个整数的文件进行排序,文件无法直接放到内存中,每个整数之多出现一次。但是对时间复杂度和空间复杂度要求很高。如何高效的实现呢?

     对于时间复杂度,因为要对文件中的整数排序,必须至少将文件内容独到内存中一次。所以时间复杂度最优为O(n)。对于排序一种最直接的想法就是使用文件磁盘排序中的merge-sort,但是这样就会增加读取文件的次数。因为我们只需要记录某个整数是否出现,所以我们只需要一个位就可以记录得到的信息。所以作者提出了使用位向量实现。

     使用位向量实现时,定义一个N元素的位向量,初始化为0,从文件中读到一个整数i,将第i位设置为1.读取文件结束后,按顺序输出位为1的下标,输出结果就是对文件中整数的排序结果。这样时间复杂度就是读取一次文件和输出文件的时间总和(位的初始化和设置相对于文件读取应该很小)。

1、空间变化

    如果文件中的数字范围过大,只是我们需要定义的位向量的大小超出了我们可使用的空间大小,那么可是多次重复来实现。比如说我们现在需要排序的整数范围是0--9990000,我们每次申请的位向量大小只有5000000大小,那么可以第一次读取文件时,只排序0-4990000之间的整数并输出,第二次读取文件时排序5000000-9990000之间的整数。依此类推,如果需要重复k次,那么时间复杂度将变为O(kn),空间复杂度不变。

2、数据变化

      在前面的实现中,我们要求每个整数至多出现一次。如果文件中的整数可以重复出现,但是出现的次数有一个上界,那么我们应该如何实现呢?

     比如说每个整数最多出现10次。这时候我们仍然可以使用位向量实现,不过这时候我们需要使用对个位来表示一个整数的信息,因为每一个整数做多出现10次,那么使用4个位就可以表示它出现的次数,这样我们就可以使用4*N大小的位向量来进行排序,用第(i-1)* 4 — i*4-1位向量来记录整数i出现的次数。

   在C++中,已经有bitset类实现了位向量,可直接使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值