华山论剑的算法 引入桶排序

华山论剑的算法

     华山论剑开始,报名名单为:郭靖,黄蓉,洪七公,欧阳锋,欧阳克,周伯通,瑛姑,黄药师,杨康,穆念慈,柯镇恶,尹志平。

     要获取所有参赛者的最终排名,该如何设计算法呢?

如果用冒泡排序、选择排序、插入排序、希尔排序、堆排序、快速排序、归并排序,可能导致一些既浪费时间又浪费表情的比赛,比如:

 洪七公 VS  尹志平

 欧阳锋 VS  欧阳克

 黄药师 VS  穆念慈

 

     可以考虑把参赛人分为四个水平段位,然后,在相同的水平段位中分别比较,这就是所谓的桶排序。

高水平洪七公  欧阳锋  周伯通 黄药师
中水平郭靖
低水平黄蓉  欧阳克  瑛姑  杨康  柯镇恶
菜鸟级穆念慈  尹志平     

浮点数的桶排序

      我们先看这样一个问题:

      问题:高考语数外三门课的满分都是150分,有N人参加这三门考试,请对考生的语数外三门课的平均分进行排序,要求时间复杂度尽可能低。

 

     基于比较的排序,时间复杂度不符合要求。计数排序(高考分数排序之计数排序)又无法处理浮点数。怎么办呢?还是来看桶排序吧。语数外三科的平均分区间是[0, 150], 且可能取小数,我们可以建立150个桶,如下:

      遍历所有待排序分数,根据值的大小,塞入到对应的桶中,这个过程的时间复杂度为O(N). 分桶的过程,揭示了桶排序的本质:不同的桶之间,不需要比较,因为左边桶中的所有元素一定小于右边桶中的所有元素,减少了很多无用的比较。

     然而,每个桶内,还是需要比较的,可以采取快速排序。假设桶的个数为M, 平均每个桶内的元素个数为N/M,  桶排序的整体时间复杂度是:

     O(N + M*N/Mlog(N/M))

     当M接近N时,上式近似简化为O(N),也就是说,此时桶排序是线性时间复杂度的排序。而当M=1时,只有一个桶,此时桶排序退化为快速排序,时间复杂度为O(NlogN). 所以,要合理选择桶的个数。

 

 

桶排序与计数排序

      回头想一下,计数排序其实是桶排序的特殊情况。计数排序时,桶中元素可能有c个完全相等的值,桶类不用排序,直接计数就可以了。比如,要对如下数据进行计数排序:

      a: {0, 1, 5, 3, 2, 2, 3, 0, 2, 6}

      可以引入7个桶:桶0中有2个0, 桶1中有1个1, 桶2中有3个2, 桶3中有2个3, 桶4中无元素, 桶5中有1个5,桶6中有1个6,如图:

      可见,计数排序确实可以看作是桶排序的特殊情况。

 

 

桶排序解决海量数据问题

     在一些场景下,桶排序可以处理海量数据问题。比如,有这样一个问题:

     在A文件中有100亿个浮点数,请对这些数据进行排序。

     显然,无法直接把100亿个数据读到内存中,bitmap也没辙了。桶排序出场,步骤如下:

     a. 创建合理的文件数,每个文件对应一个桶,遍历100亿个浮点数,归类到对应的桶中。

     b. 分别把每个桶的元素加载到内存中,快速排序后,保存到对应的桶中。

     c. 遍历每个桶的元素,写入到文件中,完成100亿个数据的排序。

    可以看到,用桶排序解决海量数据问题,其本质是分治,桶天然具有分治的能力。在笔试和面试中,桶排序常常会有妙用。    

 

     桶排序引入了桶,耗费了空间,节省了时间,这种以空间换时间的技巧,在计算机科学中无处不在。

     我们描述了桶排序的算法,也分析了算法的时间复杂度,至于程序实现,那就比较简单了,便不再赘述。掌握思路,才是最重要的。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值