分治算法解决一个最坏O(N)时间的选择问题

分治算法的一个基础定理如下

定理1:若分治算法解决一个最坏O(N)时间的选择问题,则方程分治算法解决一个最坏O(N)时间的选择问题的解是分治算法解决一个最坏O(N)时间的选择问题

意思是,把原问题分解成若干子问题,若这些子问题的规模之和没有原问题大,那么再加上处理这些子问题的分治算法解决一个最坏O(N)时间的选择问题时间,算法的时间界是分治算法解决一个最坏O(N)时间的选择问题

选择问题:在N个数中抽取第k小的,有几种解法:

1.可以用优先队列得到一个分治算法解决一个最坏O(N)时间的选择问题或者分治算法解决一个最坏O(N)时间的选择问题的时间,若k是中位数那么时间就是分治算法解决一个最坏O(N)时间的选择问题

2.可以使用快速选择算法,每次处理一个不到原问题的子问题和线性附加时间,平均时间分治算法解决一个最坏O(N)时间的选择问题,但是无法保证枢纽元的坏选择,因此最坏时间是分治算法解决一个最坏O(N)时间的选择问题

3.先将元素排序,自然可以得到第k小的数字,时间是分治算法解决一个最坏O(N)时间的选择问题

以上几种解法中,快速选择算法在实践中应用最好,但是仍然无法达到分治算法解决一个最坏O(N)时间的选择问题最坏时间,根本原因是枢纽元的选择无法保证定理1成立。一般枢纽元的选择是三数中值法,但是若3个数都是最大元,那么是坏选择;可以增加使用的数字数量,用常数时间排序,得到中位数,由于按照定理1只能有常数附加时间,因此使用的数字个数最多可以达到分治算法解决一个最坏O(N)时间的选择问题,对其进行排序,花费时间分治算法解决一个最坏O(N)时间的选择问题,显然不能超过这个数字,否则附加时间会超过分治算法解决一个最坏O(N)时间的选择问题。然而,在最坏情况下,还是不行,因为可能选择到分治算法解决一个最坏O(N)时间的选择问题个最大的元素,那么枢纽元是第分治算法解决一个最坏O(N)时间的选择问题个元素,每次处理的子问题是分治算法解决一个最坏O(N)时间的选择问题,这不是N的常数部分,无法应用定理1

五分化中项的中项:改进枢纽元选择如下:

1.把N个元素分成分治算法解决一个最坏O(N)时间的选择问题组,5个元素一组,剩余不到5个的一组可以忽略

2.找出每组的中项,得到分治算法解决一个最坏O(N)时间的选择问题个中项的表M

3.求出M的中项,将其作为枢纽元返回

定理2:使用五分化中项的中项进行枢纽元选择,快速选择算法最坏时间分治算法解决一个最坏O(N)时间的选择问题

证明:

分治算法解决一个最坏O(N)时间的选择问题,可以这样假设不影响时间界的计算,如下图:

分治算法解决一个最坏O(N)时间的选择问题

其中,每一列是5个元素的一组,中间的格子是5个元素的中项,第三行就是所有中项,所有中项的中项用Mid表示,一共2k+1组,显然有k组中,每组有3个元素比Mid大,一共3k个元素,Mid自己所在的组有2个比Mid大,一共3k+2个一定比Mid大的,比Mid小的数字数量同理,这样每次处理的子问题大小最大可以达到0.7N,就是原问题的0.7倍。

到这里得到了子问题最坏的大小,还有两项附加工作要做:

1.在每个组中,在5个元素中选择中项花费时间是常数,所有组就是分治算法解决一个最坏O(N)时间的选择问题时间

2.在0.2N个中项中选择中项,若用排序,那么需要分治算法解决一个最坏O(N)时间的选择问题时间,显然不行,因此需要对这些数字递归调用选择算法

综上,一次递归调用,解决0.7N大小和0.2N大小的两个子问题,加上O(N)线性时间,满足定理1要求,得到一个分治算法解决一个最坏O(N)时间的选择问题的最坏时间