分治算法解决一个最坏O(N)时间的选择问题
分治算法的一个基础定理如下
定理1:若,则方程
的解是
意思是,把原问题分解成若干子问题,若这些子问题的规模之和没有原问题大,那么再加上处理这些子问题的时间,算法的时间界是
选择问题:在N个数中抽取第k小的,有几种解法:
1.可以用优先队列得到一个或者
的时间,若k是中位数那么时间就是
2.可以使用快速选择算法,每次处理一个不到原问题的子问题和线性附加时间,平均时间,但是无法保证枢纽元的坏选择,因此最坏时间是
3.先将元素排序,自然可以得到第k小的数字,时间是
以上几种解法中,快速选择算法在实践中应用最好,但是仍然无法达到最坏时间,根本原因是枢纽元的选择无法保证定理1成立。一般枢纽元的选择是三数中值法,但是若3个数都是最大元,那么是坏选择;可以增加使用的数字数量,用常数时间排序,得到中位数,由于按照定理1只能有常数附加时间,因此使用的数字个数最多可以达到
,对其进行排序,花费时间
,显然不能超过这个数字,否则附加时间会超过
。然而,在最坏情况下,还是不行,因为可能选择到
个最大的元素,那么枢纽元是第
个元素,每次处理的子问题是
,这不是N的常数部分,无法应用定理1
五分化中项的中项:改进枢纽元选择如下:
1.把N个元素分成组,5个元素一组,剩余不到5个的一组可以忽略
2.找出每组的中项,得到个中项的表M
3.求出M的中项,将其作为枢纽元返回
定理2:使用五分化中项的中项进行枢纽元选择,快速选择算法最坏时间
证明:
设,可以这样假设不影响时间界的计算,如下图:
其中,每一列是5个元素的一组,中间的格子是5个元素的中项,第三行就是所有中项,所有中项的中项用Mid表示,一共2k+1组,显然有k组中,每组有3个元素比Mid大,一共3k个元素,Mid自己所在的组有2个比Mid大,一共3k+2个一定比Mid大的,比Mid小的数字数量同理,这样每次处理的子问题大小最大可以达到0.7N,就是原问题的0.7倍。
到这里得到了子问题最坏的大小,还有两项附加工作要做:
1.在每个组中,在5个元素中选择中项花费时间是常数,所有组就是时间
2.在0.2N个中项中选择中项,若用排序,那么需要时间,显然不行,因此需要对这些数字递归调用选择算法
综上,一次递归调用,解决0.7N大小和0.2N大小的两个子问题,加上O(N)线性时间,满足定理1要求,得到一个的最坏时间