使用这个算法查找第i小元素的最坏情况运行时间为O(n)。关于运行时间的证明简直屌爆了!唉,看了这么多证明,我发现其实最难的就是提出数学模型、数学描述,迈出这一步,剩下的就是凑了。
这个算法比9.2节中那个“期望运行时间才是O(n)”的RandomizedPartition算法更加牛逼,它最坏运行时间就是O(n)。之所以这么屌,是因为它每次划分都能保证是最佳划分,即“中分”。要想实现中分,就得先把中位数找出来。
算法find()过程如下:
(1)先把原数组a划分成五个一组,五个一组、、、,然后对每个小组进行插入排序,得到每个小组的中位数,组成数组b。这个函数为Select()。
(2)若b元素个数不为1,则继续对b运行步骤一。即Select()递归。直到找到中位数x。
(3)把中位数x作为一个参数,带入Partition()函数,这个函数是快速排序那个划分函数的变形。返回划分后中位数所在的下标q。
(4)q把数组a划分成两部分,如果i=q-p+1,则a[q]即为第i小元素。若i<q-p+1,则i应该在低区,在低区进行递归find()。否则,i在高区,对高区进行递归find()。
代码如下:
#include <iostream>
#include <string.h>
using namespace std;
//对每个