BFPRT算法解决的问题十分经典,即从某n个元素的序列中选出第k大(第k小)的元素,通过巧妙的分 析,BFPRT可以保证在最坏情况下仍为线性时间复杂度。该算法的思想与快速排序思想相似,当然,为使得算法在最坏情况下,依然能达到o(n)的时间复杂 度,五位算法作者做了精妙的处理。
算法步骤:
1. 将n个元素每5个一组,分成n/5(上界)组。
2. 取出每一组的中位数,任意排序方法,比如插入排序。
3. 递归的调用selection算法查找上一步中所有中位数的中位数,设为x,偶数个中位数的情况下设定为选取中间小的一个。
4. 用x来分割数组,设小于等于x的个数为k,大于x的个数即为n-k。
5. 若i==k,返回x;若ik,在大于x的元素中递归查找第i-k小的元素。
终止条件:n=1时,返回的即是i小元素。
如上图所示,在第一步分出的所有组中,除了中位数的中位数(称为x)本身所在的组和元素少于5的组外,位于x后面的组,每组比x大或者等于的元素个数为3,而在所有的中位数中,大于或等于x的中位数至少一半,所以不算那两组,比x大或者等于的数至少有:
3{[1/2*(n/5)]-2} >= 3n/10-6
类似地,至少有3n/10 - 6个元素少于或等于x,因此,在最坏的情况下,第5步中,算法的递归调用最多作用域7n/10 + 6个元素。
假设算法的最坏情况的运行时间为T(n),步骤1、2、4需要O(n)的时间。(步骤2是对大小为O(1)的集合调用O(n)次快速排序。)步骤3所需要时间为T((n/5)),步骤5所需时间最多为T(7n/10 + 6)。假设T是单调递增的,得到如下递归式
证明对某个适当大的常数c和所有的n>0,有T(n)<=cn,以证明算法的运行时间是线性的。首先,假设对某个适当大的常数c和所有的n<140,有T(n)<=cn,如果c足够大,这个假设显然是成立的。同时,还要挑选一个常数a,使得对所有的n>0,上述公式中的O(n)项所对应的函数(用来描述算法运行时间中的非递归部分)有上界an。将这个归纳假设代入上述递归式的右边,得到:
如果下式成立,上式最多是cn:
当n>70时,上述不定式等价于不等式c >= 10a(n/(n-70))。因为假设n>=140,所以有n/(n-70)<=2。因此,选择c>=20a就能够满足不等式-cn/10+7c+an<=0。(注意,这里常数140并没有什么特别之处,我们可以用任何严格大于70的整数来替换它,然后再相应地选择c即可。)因此,最坏情况下算法的运行时间是线性的。
参考 https://blog.csdn.net/maijia0754/article/details/77947167