这个算法第一次我是在sift源码里面看见的,之前一直不知道叫什么名字,知道无意间看到一篇博客,才发现了BFPRT的大名。这个名字就挺奇怪的,那是因为该算法由Blum、Floyd、Pratt、Rivest、Tarjan提出,所以就叫BFPRT。。。
此算法可以用来求元素中第k大(或小)的值或是前k大(或小)的值。个人感觉它是对快速选择算法的一种改进,快速选择算法又是基于快速排序的思想。因此本文从快速排序——快速选择算法——BFPRT算法依次讲解。
1.快速排序
一般情况下,快速排序应该是比较排序中效果最好的一种排序算法,虽然它最坏的时间复杂度可能达到O(n2)。
快速排序步骤(从小到大):
(1)首先设定一个分界值,通过该分界值将数组分成左右两部分。
(2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。
(3)重复(1)(2)步骤直至数据不能再划分为止。
具体实现如下:
第一次排序:
以第一个数为分界值,从左往右找一个比分界值大的数(7),从右往左找一个比分界值小的数(3),如果比分界值大的在小的左边,则交换两个数位置。再记录下比分界值小的数的个数,最后将分界值放入对应位置,完成第一次排序。接着对分界值左边和右边的数分别进行递归操作直到完成排序。
然后递归进行上面操作,前一个分界值(6)左边的数和右边的数分别重复第一步操作,左右之间不再比较,因为分界值右边的数都比左边的数大。