首先,什么是二分查找呢?它是一种高效率的查找算法,也称折半查找。为什么说效率高呢?让我们举个例子,A同学随便在心里想一个数,然后B同学来猜这个数,如果按照做普通的方法从1~1000便利找的话,最慢的情况会猜1000次,而如果用二分思想的话,不管他想的是什么数,B都能在10次之内猜到。(首先猜500,除了运气特别好直接猜对外不管A说太大还是太小,B都继续把可行范围缩小一半:如果太大,那么答案在1~499之间,如果太小,则在501~1000之间。只要每次选择可行区间的中点去猜,每次都能把范围缩小一半。由于log2(1000)<10,10次之内一定能猜到)
二分查找的重要条件:要查找的序列一定是单调的!
递归算法举例
#include
using namespace std;
int binarySearch(int a[],int l,int r,int key){
if (l<=r){
int mid=(l+r)>>1;
if (a[mid]==key) return mid;
else if (a[mid]>key) return binarySearch(a,l,mid-1,key);
else return binarySearch(a,mid+1,r,key);
}
return -1; //没有找到返回-1
}
int main(){
int a[5]={1,3,5,6,7};
cout<0,4,5)<//找到5的序号为2
}
迭代实现
#include
using namespace std;
int binarySearch(int a[],int l,int r,int key){
while(l<=r){
int mid=(l+r)>>1;
if (a[mid]==key) return mid;
else if (a[mid]>key) r=mid-1;
else l=mid+1;
}
return -1; //没有找到返回-1
}
int main(){
int a[5]={1,3,5,6,7};
cout<0,4,7)<//找到7的序号为4
}
尽管能用递归实现,但一般都不用递归形式的二分写法。
下面介绍一种c++STL函数库里的二分,lower_bound(),upper_bound()和binary_search().(STL里的各种数据结构真的是很实用,建议各位花些功夫学好这些)
binary_search():函数模板 :binary_search(arr[], arr[]+size , indx)。
参数说明:arr[]:数组首地址。
size:数组元素个数。
index:需要查找的值。
函数功能: 在数组中以二分法检索的方式查找,若在数组(要求数组元素非递减)中查找到indx元素则返回1,若查找不到则返回值为0。
示例:
#include
using namespace std;
int main(){
int a[5]={1,3,5,6,7};
cout<5,6)<//找到6,返回1
}
lower_bound() :函数功能: 函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置。
upper_bound():
函数功能:函数upper_bound()返回的在前闭后开区间查找的关键字的上界,返回大于val的第一个元素位置。
示
例:
#include
using namespace std;
int main(){
int a[10]={1,3,3,5,6,7,7,8,10,12};
cout<10,3)-a<<' ';
cout<10,3)-a<<' ';
cout<10,7)-a<<' ';
cout<10,7)-a<<' ';
}
//输出:1 3 5 7
二分原理易懂然而也要在刷题中慢慢提升自己对二分
下面附上一道题吧
/*问是否有x满足这个等式: 8x^4 + 7x^3 + 2x^2 + 3x + 6 == Y,x属于[0,100],可以为分数
,保留四位小数
*/
#include
#include
using namespace std;
int calculate(int x)
{
return 8*x*x*x*x+7*x*x*x+2*x*x+3*x+6;
}
int main()
{
int y;
double high=100,low=0,mid;
while(cin>>y)
{
while(low-high<1.0e-6) / /循环至high,low近乎相等
{
mid=(high+low)/2;
if(calculate(mid)<y)
low=mid;
else
high=mid;
}
printf("%.4lf\n",high);
}
return 0;
}