BFPRT算法-求数组中第K小的元素.

一、实验问题简述及分析

  1. 实验问题

求数组中第K小的元素.

  1. 问题实例

通常我们需要在一大堆数中求前 K 大的数. 比如在搜索引擎中求当天用户点击次数排名前1000的热词; 在文本特征选择中求词频值从大到小排名的前k名问题.该问题也被称作TOP-K问题.

  1. 常规算法存在的问题:

常规算法即指利用快速排序算法进行排序,快速排序的平均时间复杂度为O(nlogn),但存在时间复杂度为O(n²)的情况. 而且其实只需要前K小/大的数即可,不需要对其他多余的数进行排序,快速排序算法浪费了多余的排序时间.

  • 实验过程简述及时间复杂度分析

1. BFPTR算法

BFPTR算法,又称中位数算法. 根据算法分析,它的最坏时间复杂度最差仅为O(n).其与常规方法(即快速排序算法)差距仅在每次排序中选取的排序数字的有无规定上.在常规算法中,排序数字的选取是随机的,而在BFPRT算法中,先将数组每五个相邻的分成一组,如果最后有余下不足五个的也同样分为一组,将每组当中的中位数构成一个新数组,再求得新数组的中位数,作为选取的比较数字. 由此递归求解,保证每一次的比较数字都在数组的中间位置,最终将时间复杂度减小为O(n).

  1. 本实验步骤简述

①将原数组分组,分为五个一组,最终若有剩余不足五个的情况可以也算作一组.

②对得到的每个小组内部进行排序,取其中位数,存放在新数组中.

③找出新数组的中位数,并以该数作为比较数字m*进行partiton过程,即将比m*小的数字存在S1中,比m*大的数字放在S2中.

④判断情况一:若此时k恰好等于|m*|,输出

判断情况二:若此时k>|m*|,缩短递归 BFPRT(a, low, m.position-1, int key)

判断情况三:若此时k<|m*|,缩短递归 BFPRT(a, m.position+1,high, int key)

 图1 BFPRT算法示意图

  1. 算法的时间复杂度分析

BFPRT算法的最坏时间复杂度为O(n). 设T(n)为时间复杂度,那么很容易有如下公式 :

                                               (1)

                                                              ②                      ③

其中 ① 来自寻找分组中的中位数, ② 则来自BFPRT()过程,最初选择的m*首先大于中位数数组中的1/2,即总数的(1/2)*(n/5),而在这n/10的数中,它们又一定大于等于原5个小组中的3个数字,因此,在最坏的情况下,每次都选到7/10的部分  ③c*n来自其他过程,如排序.

  1. 实验问题思考及新尝试

在算法讲解中一直使用5为数组分组,但是为什么不使用其他数字进行分组,我在试验中用程序进行了比较.

因为偶数分组不方便取中位数,因此作不考虑 .在实验中,我选择79对原数组进行分组,发现在数组长度相同的情况下,以5分组的计算时间普遍好于以7、9进行分组的情况.

分析原因:

  1. 首先,每组的元素越多,数据的最坏情况越坏:比如7个一组,数据最坏被4:10分即2:5分,相比3:7的情况比例更高,更加不均匀.
  2. 会造成递归次数增多.

下图分别为200点情况下取5、7、9为分组的BFPRT算法结果

 5分组

7分组

  9分组

经过比较可以看出,5分组算法计算时间效率普遍最高,运行时间较快。

下图分别为500点情况下取5、7、9为分组的BFPRT算法结果

5分组

7分组

9分组

同样,经过比较可以看出,5分组算法计算时间效率普遍最高,运行时间较快。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值