对一千万条数据进行排序---编程珠玑第二版 第一章
2017-09-05 13:29
267 查看
本书第一章提出了一个看似简单的问题,有最多1000万条不同的整型数据存在于硬盘的文件中,如何在1M内存的情况下对其进行尽可能快的排序。
每个数字用4byte,1M即可存储250 000个数据,显然,只要每次对250 000个数据排序,写入到文件中即可,重复40次。
那么如何选出每次遍历的二十五万条数据呢?有如下两个策略:
1、对一千万条数据遍历40次,第i次遍历时,判断数是否属于[i*250000,i*250000+249999),如果是,则读入内存,当第i次遍历完成时,内
存中有了二十五万条数据,这些数据比前i-1次遍历筛选出来的大,但是比后40-i次遍历的小。故,将第i次遍历选入内存中的数排序,输出到硬盘文件,
追加到i-1次输出到那个文件即可。
特点:简单,粗暴,但是遍历次数极多,只能串行,对文件进行了40次读取,本机运行耗时 2分17秒214毫秒。
2、对一千万条数据遍历1次,第i组 二十五万条数据存入内存,排序,输出到文件i,对一千万条数据完成一次遍历后,生成40个内容有序的临时文件,
在对这些文件归并,即可。
特点:对源文件只需要一次读入,排序可以采用多线程,IO次数仍然较高。串行情况下,本机运行耗时21秒221毫秒
那么如何能达到10秒以内呢?
那么分析一下这个问题的特点:
a、数据不超过最大值
b、所有数据不重复
c、每条数据仅是一个数
那么可以申请一个一千万位长的位向量,下标为i的位是1,则代表存在一个数i。
3、由此得到了一种针对此问题的位图排序方法。
申请长度为一千万位的位向量bit[10000000],所有位设置为0,顺序读取待排序文件,每读入一个数i,便将bit[i]置为1。当所有数据读入完成,便对
bit做从头到尾的遍历,如果bit[i]=1,则输出i到文件,当遍历完成,文件则已排好序。本机运行耗时9秒49毫秒。
备注: 无bit类型的编程语言如何实现位操作
以32位操作系统下的int类型为例。设需要申请N个位,则需要有a[N/32+1]个int类型方可容得下N位(当然,最后一个int中有些位被浪费了)
将第i位置为1的时候可以用如下操作:
第i位必然在 int型数组a的第 (i/32)个数中,偏移量是 (i%32),将i位置为1,需要第(i/32)的数与一个数b相 或 即可,b要求是 (i%32)位为1,其他位均
为0,故有如下语句:
为了保证达到最快的运算速度,上式改写为如下:
来源:http://www.cnblogs.com/tntboom/p/4109458.html
每个数字用4byte,1M即可存储250 000个数据,显然,只要每次对250 000个数据排序,写入到文件中即可,重复40次。
那么如何选出每次遍历的二十五万条数据呢?有如下两个策略:
1、对一千万条数据遍历40次,第i次遍历时,判断数是否属于[i*250000,i*250000+249999),如果是,则读入内存,当第i次遍历完成时,内
存中有了二十五万条数据,这些数据比前i-1次遍历筛选出来的大,但是比后40-i次遍历的小。故,将第i次遍历选入内存中的数排序,输出到硬盘文件,
追加到i-1次输出到那个文件即可。
特点:简单,粗暴,但是遍历次数极多,只能串行,对文件进行了40次读取,本机运行耗时 2分17秒214毫秒。
2、对一千万条数据遍历1次,第i组 二十五万条数据存入内存,排序,输出到文件i,对一千万条数据完成一次遍历后,生成40个内容有序的临时文件,
在对这些文件归并,即可。
特点:对源文件只需要一次读入,排序可以采用多线程,IO次数仍然较高。串行情况下,本机运行耗时21秒221毫秒
那么如何能达到10秒以内呢?
那么分析一下这个问题的特点:
a、数据不超过最大值
b、所有数据不重复
c、每条数据仅是一个数
那么可以申请一个一千万位长的位向量,下标为i的位是1,则代表存在一个数i。
3、由此得到了一种针对此问题的位图排序方法。
申请长度为一千万位的位向量bit[10000000],所有位设置为0,顺序读取待排序文件,每读入一个数i,便将bit[i]置为1。当所有数据读入完成,便对
bit做从头到尾的遍历,如果bit[i]=1,则输出i到文件,当遍历完成,文件则已排好序。本机运行耗时9秒49毫秒。
备注: 无bit类型的编程语言如何实现位操作
以32位操作系统下的int类型为例。设需要申请N个位,则需要有a[N/32+1]个int类型方可容得下N位(当然,最后一个int中有些位被浪费了)
将第i位置为1的时候可以用如下操作:
第i位必然在 int型数组a的第 (i/32)个数中,偏移量是 (i%32),将i位置为1,需要第(i/32)的数与一个数b相 或 即可,b要求是 (i%32)位为1,其他位均
为0,故有如下语句:
a[i/32] | (1 << (i%32));
为了保证达到最快的运算速度,上式改写为如下:
a[i >>5] |= (1 << (i & 31));
来源:http://www.cnblogs.com/tntboom/p/4109458.html
相关文章推荐
- 对一千万条数据进行排序---编程珠玑第二版 第一章
- 编程珠玑之第一章习题5:k趟算法给1000w数据排序的测试用例
- 编程珠玑之第一章习题6给每个整数不超过10次的100w数据排序的测试用例
- 编程珠玑之第一章习题3:度量100w整数排序的运行时间
- java编程之对10个整数进行排序(从命令窗输入数据)
- 【编程珠玑】第一章电话号码排序
- 【编程珠玑】第一章位图排序
- java编程之对10个整数进行排序(从对话窗体输入数据)
- 编程珠玑第一章之产生数据1000000-9999999(二)C/C++高效实现
- JAVA对文件内数据进行排序的解决办法
- 从键盘上输入以下的数据:"TOM:89|JERRY:90|TONY:95",数据格式为“姓名:成绩|姓名:成绩|姓名:成绩”,对输入的内容按成绩进行排序,并将结果按成绩由高到低排序。
- 关于编程珠玑第一章的体会
- 数据结构与程序设计第一章:编程规则总结
- 用同一个函数名对n个数据进行从小到大排序
- Excel学习笔记002-002:工作表内及工作表间、工作簿间单元格数据的复制、剪切、粘贴;如何进行成绩排序。
- 给10^7个数据量的磁盘文件进行排序
- asp.net中对DataTable数据进行排序、检索、合并、分页、统计
- NSArray 数据对象的多个条件进行排序
- 使用hadoop进行大规模数据的全局排序