在编程珠玑和编程之美上都有讨论,这篇博客总结一下相关知识。
最一般的binary search的递归和迭代如下(默认非空):
#include
#include
#include
using namespace std;
/*
下面为递归和迭代两种,思路相同,当有重复数字时,随机的返回一个index。
*/
int binary_search_recursive(std::vector inputData,
int key, int low, int high){
if(low > high)
return -1;
else{
int mid = (high-low)/2 + low; //[编程之美]防止上溢出
if(inputData[mid] > key)
return binary_search_recursive(inputData, key, low, mid-1);
else if(inputData[mid] < key)
return binary_search_recursive(inputData, key, mid+1, high);
else
return mid;
}
}
int binary_search_iterative(std::vector inputData,
int key, int low, int high){
while(low <= high){
int mid = (high-low)/2 + low; //[编程之美]防止上溢出
if(inputData[mid] > key)
low = mid-1;
else if(inputData[mid] < key)
high = mid+1;
else
return mid;
}
return -1;
}
int main(){
int data[] = {1,2,2,2,2,3,4,5};
std::vector inputData(data, data+sizeof(data)/sizeof(int));
int key = 2;
cout << binary_search_iterative(inputData, key, 0, inputData.size()-1);
return 0;
}
/*
[编程之美]查找相同的最大坐标,这个也很容易改为查找最小坐标的。
*/
int binary_search_iterative_equality_max(std::vector inputData,
int key, int low, int high){
//1:when inputData.size() == 1, low == high; 直接到if判断。
//2:when inputData.size() >= 2, low +1 == high;
//书上说循环结束有两种情况,我觉得就是一种啊,最后总是low+1==high;
while(low+1 < high){
int mid = (high-low)/2 + low; //[编程之美]防止上溢出
if(inputData[mid] <= key)
low = mid;
else
high = mid;
}
if(inputData[high] == key)
return high;
else if(inputData[low] == key)
return low;
else
return -1;
}
我们看代码的时候一定要结合自己的分析过程,才能很彻底的理解这个算法。
一开始,我也自己根据自己的理解写了下面的代码,根据我自己的test case觉得可以的。
/*
查找相同的最大坐标
*/
int binary_search_iterative_equality_max(std::vector inputData,
int key, int low, int high){
/*
while循环结束有两种可能,
1:low+1 == high; 2:low == high;
*/
while(low+1 < high){
int mid = (high-low)/2 + low; //[编程之美]防止上溢出
if(inputData[mid] < key)
low = mid+1;
else if(inputData[mid] > key)
high = mid-1;
else
low = mid;
}
if(inputData[high] == key)
return high;
else if(inputData[low] == key)
return low;
else
return -1;
}