您的位置:首页 > 其它

算法复习笔记:二分查找

2016-04-06 17:08 323 查看
  在计算机科学中,折半搜索(英语:half-interval search),也称二分查找算法(binary search)、二分搜索法二分搜索二分探索,是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。

实现:

int binarySearch(vector<int> &v,int x)
{
int left = 0;
int right = v.size() -1;
while(left <= right)
{
int mid = left + ((right - left)>>1);
if(v[mid] == x)
return mid;
else if(v[mid] < x)
left = mid + 1;
else right = mid - 1;
}
return -1;
}


注意问题

区间开闭。left和right表示算法当前处理的数组的最小下标和最大下标,上述采用闭区间[0,v.size()-1]。采用闭区间的判断条件为left<=right,如果用left<right在最后一个元素是会直接跳出[left,left]。

中间下标计算。平均值计算能出现除法性能较低,加法可能溢出采用mid = left + ((right - left)>>1)计算可避免。

下标修改。采用+1-1修改的方式,修改之后新的区间肯定不会跟原区间一样,算法不会进入死循环。

查找第一次出现

  在v的当前区间[left,right]中,数据为非递减序, 如果tar<=v[mid],则v[mid]右边的元素(不包括v[mid])全部都不符合要求 ,则right = mid;如果tar > v[mid], 则左边的元素包括v[mid]全部都小于tar,则left = mid +1; 此时循环条件在最后一个元素的时候,会出现死循环,需要改成left<right。

比如:

   当前状况:        tar == V[0], left == 0,right == 0

   计算:          mid = 0

   更新:          更新right = mid = 0;

int binarySearchFirst(vector<int> & v,int x)
{
int left = 0;
int right = v.size()-1;

while(left < right)
{
int mid = left + ((right - left)>>1);
if(x <= v[mid])
right = mid;
else
left = mid + 1;
}
if(v[left] == x)
return left;
else
return -1;

}


查找最后一次出现

  在v的当前区间[left,right]中,数据为非递减序, 如果tar<v[mid],则v[mid]以及右边的元素全部都不符合要求 ,则right = mid - 1;如果tar >= v[mid], 则左边的元素v[mid]全部都小于tar,则left = mid ; 但是在最后两个元素的时候,循环会一直保持不变,所以采取的方法是 int mid = left + ((right - left + 1)>>1);

比如:

   当前状况:        tar == V[0], left == 0,right == 1

   计算:          mid = 0

   更新:          更新left = mid = 0;

int binarySearchLast(vector<int> &v,int x)
{
int left = 0;
int right = v.size()-1;

while(left < right)
{
int mid = left + ((right - left + 1)>>1);
if(x < v[mid])
right = mid - 1;
else
left = mid ;
}
if(v[left] == x)
return left;
else
return -1;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: