问答题 排序问题
【正确答案】
【答案解析】海量数据处理中一类常见的问题就是排序问题,即对海量数据中的数据进行排序。例如,一个文件中有9亿条不重复的9位整数,对这个文件中的数字进行排序。
针对这个问题,最容易想到的方法是将所有数据导入到内存中,然后使用常规的排序方法,如插入排序、快速排序、归并排序等各种排序方法对数据进行排序,最后将排序好的数据存入文件。但这些方法却不能在此适用,由于数据量巨大,在32bit机器中,一个整数占用4B,而9亿条数据共占用9×10 8 ×4B,大约需要占用3.6GB内存,对于32bit机器而言,很难将这么多数据一次载入到内存,更不谈进行排序了,所以此种方法一般不可行,需要考虑其他方法。
方法一:数据库排序法。将文本文件导入到数据库中,让数据库进行索引排序操作后提取数据到文件。该种方法虽然操作简单、方便,但是运算速度较慢,而且对数据库设备要求比较高。
方法二:分治法。通过Hash将9亿条数据分为20段,每段大约5000万条,大约占用5×10 6 ×4B=200MB空间,在文件中依次搜索0~5000万,50000001~1亿……将排序的结果存入文件。该方法要装满9位整数,一共需要20次,所以一共要进行20次排序,需要对文件进行20次读操作。该方法虽然缩小了每次使用的内存空间大小,但是编码复杂,速度也慢。
方案三:位图法。考虑到最大的9位整数为999999999,由于9亿条数据是不重复的,可以把这些数据组成一个队列或数组,让它有0~999999999(一共10亿个数)个元素数组下标表示数值,结点中用0表示没有这个数,1表示存在这个数,判断0或1只用1bit存储就够了,而声明一个可以包含9位整数的bit数组,一共需要10亿/8,大约120MB内存,把内存中的数据全部初始化为0,读取文件中的数据,并将数据放入内存。比如读到一个数据为341245909,那就先在内存中找到341245909这个bit,并将bit值置为1,遍历整个bit数组,将bit为1的数组下标存入文件,最终得到排序后的内容。
此类排序问题的求解方法一般都是采用上述方法。海量数据处理中与此类似的问题还有以下几种:
1)一年的全国高考考生人数为500万人,分数使用标准分,最低100分,最高900分,不存在成绩为小数的情况,把这500万考生的分数排序。
2)一个包含n个正整数的文件,每个正整数小于n,n等于1000万,并且文件内的正整数没有重复和关联数据,输出整数的升序排列。