二分搜寻无处不在,然而写好一个二分搜寻却还须要规避一些陷阱。
第一篇二分搜寻论文在 1946 年就发表了,然而第一个没有谬误的二分搜寻程序却直到 1962 年才呈现。
问题:给定一个有序数组, 蕴含【1…n】,以及一个目标值。搜寻目标值并返回。
int guessNumber(int n, int target){
int left = 1, right = n, m = 0;
while (left <= right)
{m = left + (right - left)/2;
if (m == target)
return m;
if(m > target)
right = m ;
else
left = m ;
}
return m;
}
程序看起来非常简单,且对于绝大多数数据都能执行正确。
然而,如果输出是 2,2
数组内容为;[1,2],搜寻 2.
left = 1 right = 2。m = 1
此时会陷入死循环。
正确程序:
int guessNumber(int n, int target){
int left = 1, right = n, m = 0;
while (left <= right)
{m = left + (right - left)/2;
if (m == target)
return m;
if(m > target)
right = m - 1;
else
left = m + 1;
}
return m;
}
举例 1…….m……..n
如果 m < target 阐明 target 在后半局部,则新的区间应为 [m+1,n],而非[m,n].
同理,如果 m > target, 阐明 target 在前半部分,新区间应为:[1,m-1], 而非[1,m].