所谓的二分查找呢,其实就是一种简化版的查找吧,只不过不同于完全版的遍历,它是通过对顺序非降次数列的折半去减少遍历的次数从而降低查找元素时的时间复杂度。
首先我们定义两个变量进行动态储存,分别是L和R,就是left和right,他们的起始位置分别是数组的最左边和最右边。然后就是找出中间数mid,我习惯性将mid的表达式写成mid=(l+r+1)/2;也就是向上求商,这样可以避免数组长度奇偶性的影响。然后就是确定所搜数key的范围了,对,就是用key去和mid进行比较,下面来分类讨论一波:
1.key小于mid的情况:
这说明key在该数组的前半部分,这时候就应该重新确定right的位置,我喜欢把right设为mid-1。而后mid也就因此改变。
2.key大于mid的情况:
这就是key在数组的后半部分,重新刷新left的位置,一般设为mid=right,随后mid被更新,
3.key等于mid的情况:
那还等什么呀兄弟,你找的东西已经找到了,这时候只要根据题目要求,如果是找出相同的第一个元素,那么就从mid向前依次搜索直到不是该元素。如果是找最后一个元素的话只需要向后搜索就好。
上代码
#include<iostream>
#include<cstdio>
using namespace std;
int Bsearch( int key,int n )//找到数组中大于数字key的所有元素中最小的那个。
{
int l=0,r=n-1,mid;
int a[1000];
if( key==a[r] )
l=-1;
else if( key<a[0] )
l= a[0];
else
{
while( l<r )
{
mid=(l+r+1)/2;
if( key<a[mid] )
r=mid-1;
else if( key>a[mid] )
l=mid+1;
else
l=mid;
}
l= a[l+1];
}
return l;
}
int main()
{
int a[1000],n,key;
cin>>n>>key;
for( int i=0;i<n;i++ )
cin>>a[i];
cout<<a[0]<<endl;
cout<<Bsearch(key,n )<<endl;
return 0;
}