二分搜寻无处不在,然而写好一个二分搜寻却还须要规避一些陷阱。
第一篇二分搜寻论文在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].