一、概念
在二分查找的基础上,在左(右)区间上在进行一次二分,这样的查找算法称为三分查找。
用途:通常用来确定最值。
适用条件:搜索序列为凸序列,即该序列存在最大(小)值,在最大值(最小值)的左侧序列,必须满足不严格单调递增(递减),右侧序列必须满足不严格单调递减(递增)。
如下图,表示一个有最大值的凸性函数:
算法描述:
(1) 先取整个区间的中间值
MidL = ( Left + Right ) / 2;
(2) 再选取右(或左)区间的中间值
MidR = ( MidL + Right ) / 2;
(3) 通过比较Mid1与Mid2中谁最靠近最大(小)值,保留最靠近最大(小)值的Mid,然后缩小区间。
如上图,mid比midmid更靠近最大值,保留mid,舍弃midmid的右区间。
if ( cal(MidL) > cal(MidR) )
Right = MidR;
else
Left = MidL;
(4)重复步骤(1)(2)(3),直至找到最大(小)值。
实现代码:
const double EPS = 1e-10; // 精度
double Calc( double x ); // 函数
double TernarySearch( double Low, double High )
{
double MidL, MidR;
while( Low + EPS < High )
{
MidL = ( Low + High ) / 2;
MidR = ( MidL + High) / 2;
double MidL_Val = Calc( MidL );
double MidR_Val = Calc( MidR );
if ( MidL_Val > MidR_Val )
High = MidR;
else
Low = MidL;
}
return Low;
}
算法复杂度:O(log3 |High - Low| )