上一次求职已经差不多4年前的事了,印象中二分查找法在算法笔试中的出现频率是比较高的。
思路:
二分法的思路比较简单,给出一串有序数组(这里选假定是由小至大排序的),算出位于数组中间的下标,然后比较此下标对应的数值是否是要找的数值(目标数),如果小于目标数,就从左半部分继续找,大了就在右半部分找,查找的方法还是一样——算出位于“新数组”中间位置的下标,比较数值,如此类推,直至找到或遍历完为止。
下面先按思路写一段:
int binary_search_(int arr[], int left, int right, int val)
{
int mid;
if(left > right)
{
return -1;
}
mid = (right+left)>>1;
if(arr[mid] < val)
{
left = mid+1;
}
else if(arr[mid] > val)
{
right = mid-1;
}
else
{
return mid;
}
return binary_search_(arr, left, right, val);
}
int binary_search(int arr[], int size, int val)
{
int left = 0;
int right = size-1;
if(!arr)
{
return -1;
}
return binary_search_(arr, left, right, val);
}
此方法是通过递归的方式实现的,如果数据量大的话,函数调用花销不可小看。下面不用递归的方式改造一下:
int binary_search(int *arr, int size, int val)
{
int left = 0;
int right = size-1;
int mid;
if(!arr)
{
return -1;
}
while(left <= right)
{
mid = (left + right)>>1;
if(arr[mid] < val)
{
left = mid+1;
}
else if(arr[mid] > val)
{
right = mid-1;
}
else
{
return mid;
}
}
return -1;
}
代码是写完了,但有没有BUG呢?
参考90%无法正确实现二分查找,正如题目所说,上面代码被归为90%的行列了
此错误正是本码奴经常犯的且最折腾人的错误——
mid = (left + right)>>1;
溢出了。
只用做一个小巧的改动:
mid = left + (right-left)>>1;
(完)