一看就懂的大数据排序算法:如何给100万用户数据排序?

看图说话啊。

桶排序的时间复杂度,是O(n),如果不出意外的话。

如果要排序的数据有 n 个,我们把它们均匀地划分到 m 个桶内,每个桶里就有 k=n/m 个元素。每个桶内部使用快速排序,时间复杂度为 O(k * logk)。m 个桶排序的时间复杂度就是 O(m * k * logk),因为 k=n/m,所以整个桶排序的时间复杂度就是 O(n*log(n/m))。当桶的个数 m 接近数据个数 n 时,log(n/m) 就是一个非常小的常量,这个时候桶排序的时间复杂度接近 O(n)。

那既然桶排序这么的优秀,为什么我们在平时的使用中却偏向于其他的排序方法呢(大多数情况下偏向于时间复杂度为O(nlogn)的快排)?

桶排序的小缺点

桶排序对要排序数据的要求是非常苛刻的。

首先,要排序的数据需要很容易就能划分成 m 个桶,并且,桶与桶之间有着天然的大小顺序。

其次,数据在各个桶之间的分布是比较均匀的。如果数据经过桶的划分之后,有些桶里的数据非常多,有些非常少,很不平均,那桶内数据排序的时间复杂度就不是常量级了。

桶排序比较适合用在外部排序中。所谓的外部排序就是数据存储在外部磁盘中,数据量比较大,内存有限,无法将数据全部加载到内存中。

比如说我们有 10GB 的数据,我们希望对这波数据进行排序,但是我们的内存有限,只有1G,没办法一次性把 10GB 的数据都加载到内存中。这个时候该怎么办呢?

我们可以先扫描一遍文件,看数据所处的数据范围。假设经过扫描之后我们得到,数据最小为1,最大为1000。我们将所有数据划分到 100 个桶里,第一个桶我们存储在 1 元到 10 元之内的数据,第二桶存储在 11 元到 20 元之内的数据,以此类推。每一个桶对应一个文件,并且按照数据范围的大小顺序编号命名(00,01,02…99)。

理想的情况下,如果数据均匀分布,那数据会被均匀划分到 100 个文件中,每个小文件中存储大约 100MB 的数据,我们就可以将这 100 个小文件依次放到内存中,用快排来排序。等所有文件都排好序之后,我们只需要按照文件编号,从小到大依次读取每个小文件中的数据,并将其写入到一个文件中。

不过呢,不均匀才是常态嘛,有可能某个区间的数据特别多,划分之后对应的文件就会很大,没法一次性读入内存。这又该怎么办呢?

针对这些划分之后还是比较大的文件,我们可以继续划分。

如果划分之后,数据还是太多,无法一次性读入内存,那就继续再划分,直到所有的文件都能读入内存为止。


计数排序(Counting sort)


计数排序其实是桶排序的一种特殊情况。

还是上面那个例子来说,区间跨度为1000,那就分它一千个桶,每一个数据位一个桶。

我们就当这波数据都是整数,所以并不需要再进行排序。我们只需要依次扫描每个桶,将桶内的数据依次输出到一个文件中,就实现了 10G 数据的排序。因为只涉及扫描遍历操作,所以时间复杂度是 O(n)。

计数排序的小缺点

那这不也很明显嘛,我桶排序就开100个桶,运气不好多开几个,计数排序一上来就是1000个桶预订了,其中会有多少浪费,多少空桶,谁知道呢?

计数排序只能用在数据范围不大的场景中,如果数据范围 k 比要排序的数据 n 大很多,就不适合用计数排序了。而且,计数排序比较适合给非负整数排序(不然刚刚为什么要假设),如果要排序的数据是其他类型的,要将其在不改变相对大小的情况下,转化为非负整数。


基数排序(Radix sort)


我们再来看这样一个排序问题。假设我们有 10 万个手机号码,希望将这 10 万个手机号码从小到大排序,你有什么比较快速的排序方法呢?

这十一位的数,桶一个我看看?

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

需要这份系统化资料的朋友,可以戳这里获取

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值