zoukankan      html  css  js  c++  java
  • 怎样对千万级甚至亿级数据量排序

    编程珠玑第二版第一章就有类似的问题,问题描述如下:

    有最多1000万条不同的整型数据存在于硬盘的文件中(数据不超过最大值),如何在1M内存的情况下对其进行尽可能快的排序。

    数据特征:单个数据<=1000万、不同的(没有重复)、整型(int,4B)
    
    要求:1M内存、尽可能快
    
    分析:1MB = 1*1024*1024 B   能存储大于25万个int类型的整数。所以每次我们可以排序25万条记录,一共排序40次。

    (1)一个简单的思路是读1000万条1次,对第i个25万条数据进行排序,并将排好的结果存成外部文件i(这里可以用常见的内部排序,如快排),最后我们生成了40个排好序的外部文件,然后对这40个文件进行归并排序输出成1个文件。

    (2)更好的思路是位向量排序,我们可以申请一个1千万长度的位向量bit[10000000],所有位设置为0,顺序读取待排序文件,每读入一个数i,便将bit[i]置为1。当所有数据读入完成,便对 bit做从头到尾的遍历,如果bit[i]=1,则输出i到文件,当遍历完成,文件则已排好序。

    这个思路和桶排序一样,算法的关键是位向量。对于不支持bit数据结构的语言我们可以自己实现位操作,int是32位的,所以我们需要[1千万/32+1]个int类型存储,大约1.2M。(虽然差点不符合题目的要求,但是不失为一种更好的解题思路)。

    将第i位置为1的时候可以用如下操作:

    a[i/32] | (1 << (i%32)); 

    第i位肯定在i/32个int上,i%32是偏移量,然后通过按位或来将特定位置1。(不明白的可以了解一下位计算)

    为了计算速度更快,上述公式可以完全由位运算替代:

    a[i >>5] |= (1 << (i & 31));

    总结

    对于大的数量级的排序,基本思路是分而治之的思想,位向量方法虽然效率很高,但是要注意一些限制条件(数据不能重复、不适合稀疏的数据分布等)。

    编程珠玑中的例子是int型的数据排序,实际我们面临的问题可能不会这么简单,例如需要对复杂数据类型进行排序(对象),我们可以让对象实现compareTo,重写hashcode、equals等等。

  • 相关阅读:
    TP5 try{}catch{}异常捕获不到 解决办法
    layui2.5 开关在confirm确认了之后在关/开
    JQuery 表单textarea控制字数
    Navicat Premium从远程Mysql数据库复制到本地数据库的方法
    dedecmsV5.7 任意文件上传漏洞修复
    PHP 利用PHPExcel到处数据到Excel;还有导出数据乱码的解决方案。
    Mac Pro 2017款自带php与用brew重装PHP后的地址
    用js传递当前页面的url,丢失了&后面的参数 解决办法
    PHP 超全局变量之$_SERVER
    Linux while和for循环简单分析
  • 原文地址:https://www.cnblogs.com/ouym/p/9361171.html
Copyright © 2011-2022 走看看