线形排序

线形排序

线形排序,就是时间复杂度为O(n)的排序算法,桶排序、计数排序、基数排序都是线形排序,之所以能做到线形排序的原因,是因为他们都是基于非比较的排序算法,都不涉及到元素之间的比较操作,线形排序的应用都是比较局限的,都是应用于特定的排序场景的。应用不是很广泛,但是如果数据的特征符合他们的特点,那么利用线形排序进行操作,会特别高效的。

2.桶排序

桶排序顾名思义就会用到痛,核心思想就是将要排序的数据分到几个有序的桶里。每个桶里边的数据再单独进行排序,再把每个桶里的数据按照顺序依次取出,组成的序列就是有序的了。

桶排序的时间复杂度

假设有n个数据分到了m个桶中,每个桶中的数据就是k=n/m个,每个桶中的数据通过快速排序的时间复杂度为O(klogk),那么m个桶的时间复杂度相加就为O(nlogk),k=n/m,当m趋紧与n的时候logk就为1,所以桶排序的时间复杂度就接近与O(n)。

桶排序的使用场景

既然桶排序的时间复杂度为O(n),比快速排序的效率还高,为什么不用桶排序代替其他的排序算法呢,实际上桶排序对数据的要求是非常苛刻的,应用十分局限。

1.桶排序要求数据能够很容易的划分出来m个桶,并且桶与桶之间有着大小顺讯,这样所有的铜排完,只需要按照顺序排序数据就可以了。

2.桶排序还需要每个桶里边的数据事均匀分布的,如果某个桶里边的数据出现特别多的情况,很不均匀,他的时间复杂度就不再是常量级别的了,极端的情况下还会退化到快速排序的时间复杂度。、

3.**桶排序适合用在外部排序中。**外部排序:数据存储在外部磁盘中,数据量特别大,内存有限,不够存储。

分析一个案例:
假设有5gb的订单,希望按照订单金额进行排序,但是内存很小,只有几百兆,没办法一次性的把这些订单的数据进行排序,怎么办?

利用桶排序的思想就可以解决,首先扫描一下所有订单的数据,找到订单金额的范围,假设范围在1到10万之间,可以把范围分成100个桶(文件),每个桶里存储1000个范围,从1开始,然后对每个区间里边的订单进行排序,

最后按照顺序合并这100个文件,的到的数据就是我们需要的数据了。

如果有到某个区间的数据特别多的情况下怎么办,对这个区间继续进行分区。放在n个桶中去。

2.计数排序

计数排序就是桶排序的一种特殊情况。就是排序的时候数据的范围是m,我们就直接分成m个桶,每个桶内的数据都是相同的,省掉了桶排序的时间。

那高考来举例。假设我们省的考生有一百万,怎么进行排序呢?

考生的分数范围都是在0-900之间的,我们就把考生的数据按照0-900分成901个桶,对应的分数就是0-900,每个桶里边放的就是对应分数的同学。然后再将数据放到一个数组中或者一个文件中,就实现了对考生分数的排序,他的时间复杂度也是O(n)。

计数排序为什么叫做计数排序呢?

计数排序的算法实现方式:

假设现在有十个考生,分数在0-6之间,分数记录在一个数组中A[n]={0,1,3,4,3,5,6,3,0,2}。

现在需要一个数组C(m)记录每个分数出现的次数C(m)={2,1,1,3,1,1,1},C(m)就代表桶。0 的位置放置的就是分数为0的同学,一次每个位置放置的就是各个分数的同学数量。

然后我们让S(m)={2,3,4,7,8,9,10},可以看出他存储的就是<=改分数学生的数量,然后从后向前扫描数组A[n],放到一次放到数组R[n]中。

例如第一个去到的数据是2,就取出S(m)索引为二的数据为4,也就是说2是数组中的第四个元素(放到R[n]中对应的索引就是3),然后把S(2)的值-1,继续进行下边的操作,取出完所有的数据后的到的数组就是一个有序数组了。从后往前去可以保证计数排序是一个稳定的排序算法。

3.基数排序

直接来说基数排序的应用案例:

对手机号进行排序,假设有十万个手机号,进行排序,怎么进行排序。

其实非常简单,快速排序也可以做到但是效率太低,桶排序计数排序,手机号的范围太大,也不适合,接下来就用到了基数排序了,就是先对手机号的最后一位进行排序,然后倒数第二位,知道手机号的最后一位,排序出来的数据就是一个有序的了。

为什么这样排序出来的数据就是有序的了,因为只要高位中一个手机号比另一个手机号大,那么其他的位数就不用看了。而且我们需要使用一个稳定的排序,使用不稳定的排序进行排序的话,会出现高位相同的情况下打乱原来排序好的数据的顺序,数据就不是有序的。

每一位的排序可以用桶排序或者计数排序,时间复杂度为O(n),要排序的数据为k位,那整体的时间复杂度就为

O(kn),因为k是有限的所以基数排序的时间复杂度就近似于O(n)。

实际上要排序的数据往往都不是等长的,这样我们就需要对数据进行处理,利用的其实就是除法的思想讲这些数据归位一类,进行处理。

堆排序

堆排序的时间复杂度和快速排序的时间复杂度一样,有兴趣的可以看下我的这篇博客堆排序

排序总结

-排序--时间复杂度--原地排序--稳定性-
冒泡排序O(n^2)稳定
插入排序O(n^2)稳定
选择排序O(n^2)不稳定
归并排序O(nlogn)不是稳定
快速排序O(nlogn)不稳定
堆排序O(nlogn)不稳定
桶排序O(n)稳定
计数排序O(n)稳定
基数排序O(n)稳定

在实际开发中并不是时间复杂度越小越好比如线形排序,就需要非常特定的场景,而且数据量小的时候时间复杂度为O(n^2)的有可能比O(nlogn)更高,因为我们分析时间复杂度的时候往往都是去掉参数,和常量的。所以根据具体的场景选择具体的排序就是仁者见仁,智者见智的事情了,大家可以分析一下java的排序,他就是根据具体的数据量选择不同的排序算法的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值