对有 5 亿整数的大文件排序

一、需求

有1个大文件包含5亿个数(文件大小好几个G),其中每一行都是一个随机整数(不重复),现在要对这个文件进行排序。

二、实现

2.1 位图法

核心思想是,创建一个拥有5亿bits的BitSet(位图),BitSet每一位初始时都为false。然后读取包含正整数的文件,对于每一个数i,将bitSet[i]设置为true。最后遍历位图,如果bitSet[j]为true,那么输出 j。

采用位图法,也可以判断某个给定的数是否在大文件中,只需要判断bitSet的指定位是否为true即可。

下面是我写的一个简单的demo,用于对文件中的数字排序:

data.txt内容如下:

代码如下:

public static void main(String[] args) {
        BitSet bitSet = new BitSet(100);

        try (BufferedReader br = new BufferedReader(new FileReader("F:\\data.txt"))) {
            String line = null;
            while ((line = br.readLine()) != null) {
                int value = Integer.valueOf(line);
                bitSet.set(value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        for (int i = 0; i < bitSet.length(); i++) {
            if (bitSet.get(i)) {
                System.out.println(i);
            }
        }
    }

结果如下:

1
7
9
12
32
43
87
765
32543

2.2 外部排序

在内存极小的情况下,采用分治策略,利用外存保存中间结果,再用多路归并来排序。

map-reduce思想:

内存中维护一个极小的缓冲区buffer,将大文件bigdata按行读入,直到buffer满或者大文件读完时,对buffer中的数据调用内排进行排序,排序后将有序结果写入磁盘临时文件bigdata.xxx.part.sorted,循环利用buffer直到大文件处理完毕,得到n个有序的临时文件。

接下来,对n个有序的临时文件进行归并排序,方法如下:假如有三个临时文件,其中文件1:3,6,9,文件2:2,4,8,文件3:1,5,7。

第一回合:文件1的最小值:3 , 排在文件1的第1行,文件2的最小值:2,排在文件2的第1行,文件3的最小值:1,排在文件3的第1行 那么,这3个文件中的最小值是:min(1,2,3) =1。也就是说,最终大文件的当前最小值,是文件1、2、3的当前最小值的最小值。上面拿出了最小值1,写入大文件。

第二回合:文件1的最小值:3,排在文件1的第1行,文件2的最小值:2,排在文件2的第1行,文件3的最小值:5,排在文件3的第2行。那么,这3个文件中的最小值是:min(5,2,3) = 2,将2写入大文件。

接下来,重复上述操作,直到所有小文件的内容都写到了大文件。

 

参考:

https://blog.csdn.net/zxx901221/article/details/83028481

https://mp.weixin.qq.com/s?__biz=MzUzMTA2NTU2Ng==&mid=2247488950&idx=2&sn=a3f4a09acd07638055c803338c15e29e&chksm=fa496a07cd3ee3117a27f17818ddc4152a817b50961780ae65ce3ac545303092221b08778e16&mpshare=1&scene=1&srcid=&sharer_sharetime=1582344585643&sharer_shareid=cfcd208495d565ef66e7dff9f98764da&key=56dae8b8a643d0f33cf6fdae6748f10f94d93459951fc0f564b244e54c6e8de6cce77ff794210f989a83231ae733a61f773233f7a4f5cbe90fac0ba3b3f194898dacea95b4b6667befc1c49ea94fd347&ascene=1&uin=MjI5NzkwNjI0Mg%3D%3D&devicetype=Windows+10&version=62070158&lang=zh_CN&exportkey=A9Ay4nz6HZO2bU0iugefePI%3D&pass_ticket=FW9GJdVHO2LjxiXcRXeofaBYJdcXuPY6k3di%2BzwOyVBLknE63w20ogQQfIUitcCY

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值