大数据算法:对5亿数据进行排序
来源:互联网 发布:英语语法 视频 知乎 编辑:程序博客网 时间:2024/05/18 03:00
前言:
在大数据研究的路上,我们总要对一些很大的数据进行各种各样的操作。比如说对数据排序,比如说对数据统计,比如说对数据计算。而在大量的数据面前,我们总是束手无策,因为我们无法在限定时间的情况下,在效率上做到让人满意,也无法在限定空间的情况下,能够快速解决问题。可能我们在一些日常的开发过程中,没有遇到过这些问题。不过,现在是时候来考虑一下这样的问题了。因为,现在正值大数据的时代。
在本文中我会用三种方法,从两个方面来说明如何解决对5亿数据进行排序工作。
本文链接:http://blog.csdn.net/lemon_tree12138/article/details/48783535 -- 编程小笙
--转载请注明出处
思路分析:
拿到这样的一个问题,你的第一感觉是什么?冒泡排序?选择排序?插入排序?堆排?还是快排?可能你的想法是我的内存不够。的确,这么大的一个数据量,我们的内存的确不够。因为单是5亿的整数数据就有3.7个G(别说你是壕,内存大着呢)。既然内存不够,那么我们要怎么来解决呢?
要知道我们一步做不了的事,两步总能做到。那么我们就来尝试第一步做一些,剩下的一些就等会再来搞定吧。基于这样的思路,就有下面的一个解题方法——分治!
1.分治——根据数据存在文件中的位置分裂文件到批量小文件中
相对于朴素的排序,这是一种比较稳妥的解决方法。因为数据量太大了!我们不得不将大事化小,小事化了。
这里我们的做法是每次读取待排序文件的10000个数据,把这10000个数据进行快速排序,再写到一个小文件bigdata.part.i.sorted中。这样我们就得到了50000个已排序好的小文件了。
在有已排序小文件的基础上,我只要每次拿到这些文件中当前位置的最小值就OK了。再把这些值依次写入bigdata.sorted中。
2.分治——根据数据自身大小分裂文件到批量小文件中
按照数据位置进行分裂大文件也可以。不过这样就导致了一个问题,在把小文件合并成大文件的时候并不那么高效。那么,这里我们就有了另一种思路:我们先把文件中的数据按照大小把到不同的文件中。再对这些不同的文件进行排序。这样我们可以直接按文件的字典序输出即可。
3.字典树
关于字典树的基本使用,大家可以参见本人的另一篇博客:《数据结构:字典树的基本使用》
基于《数据结构:字典树的基本使用》这篇博客中对字典序的讲解,我们知道我们要做就是对字典树进行广度优先搜索。
结构设计图:
代码分析:
0.分治
(0)分割大文件
此步对大文件的分割是按序进行的,这样我们就可以确保数据的离散化,不会让一个小文件中的数据很多,一个小文件的数据很少。
(1)排序
即使是已经切割成小份的了,不过每个小文件中的数据集仍然有50000个。因为50000个数据也不是一个小数据,在排序的过程中,也会有一些讲究,所有这里我们使用的是快排。如下:
(2)合并
在合并的时候,我们要明确一个问题。虽然我们的单个小文件已经有序,不过我们还并不知道整体的顺序。比如:
文件1:1 2 4 6 9 34 288
文件2:4 5 6 87 99 104 135
上面的两个文件虽然每个文件内部已经有序,不过整体来说,是无序的。对于在单个文件有序的基础上,我们可以做一些事情。我们可以把每个文件中的数据看成是一个队列,我们总是从队列的首部开始进行出队(因为队列的头部总是最小的数)。这样,我们就把问题转化成从N个小文件中依次比较,得到最小的结果并记入文件(当然,我们不可以生成一个数就写一次文件,这样太低效了,我们可以使用一个变量缓存这此"最小值",在累计到一定数量之后再一次性写入。再清空变量,循环反复,直到文件全部写入完毕)。
注:这里关于分治的算法,我就只提供一种实现过程了。可能从上面的说明中,大家也意识到了一个问题,如果我们把大文件中的数据按照数值大小化分到不同的小文件中。这样会有一个很致命的问题,那就是可能我们的小文件会出现两极分化的局面,即有一部分文件中的数据很少,有一部分小文件中的数据很多。所以,这里我就不再提供实现过程,在上面有所说明,只是想说我们在解决问题的时候,可能会有很多不同的想法,这些想法都很好,只是有时我们需要一个最优的来提升逼格(^_^)。
1.字典树
因为我们知道字典树是可以压缩数据量的一种数据结构,尤其是针对那么使用的字符串个数有限(比如:'0','1','2','3','4','5','6','7','8','9'),并整体数量很多的情况。因为我们可以可以让同一个字符重复使用多次。比如:"123456789"和"123456780"其实只使用了'0'-'9'这10个字符而已。关于字典树的实现,我想是很简单的一种方法。如果你还是感觉有些朦胧和模糊的话,就请参见本人的另一篇博客《数据结构:字典树的基本使用》,在那一篇博客中,我有很详细地介绍对字典树的各种基本操作及说明。
这里我还是贴出一部分关键的代码,和大家一起学习吧。代码如下:
(0)将数据记入文件
(1)对字典树进行广度优先搜索
小结:
在大数据的探索还远不止于此。还有很多东西等着我们去了解,去发现,以及创造。
而对于大量数据的问题,我们可以利用分治来化解它的大,从而可以更方便地去观察全局。也可以使用我们已经学习过的一些数据结构及算法来求解问题。不过随着我们不断地学习,不断地探索,我们可能会感觉到自己学习的一些固有的数据结构和算法并不能完全地解决我们遇到的问题,那么就需要我们的创造力了。
- 大数据算法:对5亿数据进行排序
- 大数据算法:对5亿数据进行排序
- 大数据算法:对5亿数据进行排序
- 大数据排序算法
- 简单模拟对大数据进行排序的整个过程
- 对大量数据进行排序
- 对json数据进行排序
- SQLSERVER 对数据进行排序
- 大数据之使用hadoop对海量数据进行统计并排序
- 大数据排序算法总结
- 对大对象进行排序的算法
- 九大排序算法-大数据
- 如何对大数据软件产品进行测试?
- 客户端对数据进行重新排序
- 对数据进行乱序排序
- 对结构体中的数据进行排序
- 使用vim对数据进行排序
- 客户端对数据进行重新排序
- js关闭当前页面(窗口)的几种方式总结(原文:http://www.jb51.net/article/34502.htm)
- HDU 4165 Pills【卡特兰数】
- 极乐技术周报(第十六期)
- Tensorflow 实现CNN
- java数据结构与算法之双链表设计与实现
- 大数据算法:对5亿数据进行排序
- 网络包的转发流程详解实例说明
- 容易_167_链表求和(3)
- Eclipse项目移植到Android studio问题及处理办法
- 在 Linux 下判断系统当前是否开启了超线程
- 12 个学习新的编程语言的方法
- 【Spring】- Bean的生命周期的init和destroy方法的三种方式
- Peewee中文文档【一】:安装与测试
- session和cookie笔记