如何给100亿个数字排序?
来源:互联网 发布:常用的nosql数据库 编辑:程序博客网 时间:2024/05/17 06:26
场景
之前写过一篇海量数据中统计ip出现次数最多的博客,今天再写篇类似的,当然会有不同的地方,相同的地方我快速写过,详细的可以看之前的博客。
今天要给100亿个数字排序,100亿个 int 型数字放在文件里面大概有 37.2GB,非常大,内存一次装不下了。那么肯定是要拆分成小的文件一个一个来处理,最终在合并成一个排好序的大文件。
实现思路
1.把这个37GB的大文件,用哈希分成1000个小文件,每个小文件平均38MB左右(理想情况),把100亿个数字对1000取模,模出来的结果在0到999之间,每个结果对应一个文件,所以我这里取的哈希函数是 h = x % 1000,哈希函数取得"好",能使冲突减小,结果分布均匀。
2.拆分完了之后,得到一些几十MB的小文件,那么就可以放进内存里排序了,可以用快速排序,归并排序,堆排序等等。
3.1000个小文件内部排好序之后,就要把这些内部有序的小文件,合并成一个大的文件,可以用二叉堆来做1000路合并的操作,每个小文件是一路,合并后的大文件仍然有序。
- 首先遍历1000个文件,每个文件里面取第一个数字,组成 (数字, 文件号) 这样的组合加入到堆里(假设是从小到大排序,用小顶堆),遍历完后堆里有1000个 (数字,文件号) 这样的元素
- 然后不断从堆顶拿元素出来,每拿出一个元素,把它的文件号读取出来,然后去对应的文件里,加一个元素进入堆,直到那个文件被读取完。拿出来的元素当然追加到最终结果的文件里。
- 按照上面的操作,直到堆被取空了,此时最终结果文件里的全部数字就是有序的了。
最后我用c++写了个实验程序,具体代码在这里可以看到。
思维拓展
类似的100亿个数字求和,求中位数,求平均数,套路就是一样的了。
求和:统计每个小文件的和,返回给master再求和就可以了。
求平均数:上面能求和了,再除以100亿就是平均数了
求中位数:在排序的基础上,遍历到中间的那个数就是中位数了。
更正,评论中网友马敬v,提出了不用对数字进行哈希,直接平均分成1000份,进行内部排序后,直接进行 k 路归并排序,也是可以的。
阅读全文
0 0
- 如何给100亿个数字排序?
- 如何给100亿个数字排序?
- 如何给100亿个数字排序?
- 给15个数字排序
- 100亿个数字排序
- 如何给10^7个不同的数字的磁盘文件排序
- 15电气李丹【给15个数字排序】
- 如何给10^7个数据量的磁盘文件排序
- 如何给10^7个数据量的磁盘文件排序
- 如何给10^7个数据量的磁盘文件排序
- 如何给10^7个数据量的磁盘文件排序
- 如何给10^7个数据量的磁盘文件排序
- 如何给10^7个数据量的磁盘文件排序
- 如何给10^7个数据量的磁盘文件排序
- 如何给10^7个数据量的磁盘文件排序
- 如何给10^7个数据量的磁盘文件排序
- C++实现100个数字排序
- 从1亿个数字中取出最大的100个数字- 位图排序(空间换时间)
- 我的第一次h5 五子棋游戏作品
- google的glog日志管理
- 剑指offer面试题15 链表中倒数第K个结点
- 数据结构与算法(java)——链表
- 频道循环,每个子栏目下,自动加广告位
- 如何给100亿个数字排序?
- Linux更换默认软件源
- javascript之面向对象编程续
- Unity3d 序列目标点的移动
- 【剑指offer】题32:从1到n整数中1出现的次数
- spring 整合 redis,以及spring的RedisTemplate如何使用
- Python中join的简单用法
- 滑动窗口的中位数
- Hibernate学习笔记(二)