之前写的二分算法的模板 现在略作更新
标准的二分算法的形式是:
template<class Typep> int BinarySearch(Type a[],const Type& x,int n) // 总共n个值 数组从0开始 { int left=0; int right=n-1; while(left<=right){ int middle=(left+right)/2; if(a[middle]==x)return middle; //返回查找到的位置 if(a[middle]>x)right=middle-1; else left=middle+1; } return -1; //没有找到 }
但是往往题中给出的不是数组中的数,需要在数组中找到比查找的值刚刚大的数,那么我们就需要改动return -1;的值 那么改到什么最好呢?
下面我们就来证明
a[1] a[2] a[3]
10 20 30
a[1]=10; a[2]=20; a[3]=30;
现在我们要查找15;
(1)查找的范围值[1,2] ------这里指的是数组的位置
left=1,right=2;
进入while 循环中
middle=1;
num>a[middle]=a[1];
left=middle+1;
result: left=2; midddle=1,right=1;
跳出循环
(2) 查找的范围是[1,3]
left=1,right=3;
进入while循环
middle=2;
num<a[middle]=a[2]
right=middle-1=1;
middle=2,left=1;
进行第二次循环
middle=1;
a[middle]<num
left=middle+1=2;
left=2; middle=1,right=1;
因为是二分查找的情况 所有的情况都会演变成[1,2]和[1,,3]的情况
然后如果要找刚刚大于一点的 选择left的
若是要找刚刚小于一点的 选择right
---- 上面的这两句话就是更改最后一个return 的值 是他返回left和right
然后要注意的是 可以再所给集合中多添加两个边界值 使之 将所有的范围固定 这样就可以求解了
举个例子
要对下面的8个数进行2分查找
2,55,6,7,35,34,88,56
我们加上两个边界值 -1000和1000 控制范围
#include<stdio.h> #include<iostream> #include<algorithm> using namespace std; int a[10]={-1000,1000,2,55,6,7,35,34,88,56}; int BinarySearch(int n,int num){ int left=0; int right=n-1; int middle; while(left<=right){ //printf("left=%d right=%d\n",left,right); middle=(left+right)/2; if(a[middle]==num)return middle; if(a[middle]>num)right=middle-1; else left=middle+1; } return left; //刚刚大于一点的 } int main() { sort(a,a+10); int n=10; //8个查找数加上两个范围 int num; for(int i=0;i<10;i++) printf("%d ",a[i]); printf("\n"); while(scanf("%d",&num)!=EOF){ int pos=BinarySearch(n,num); printf("pos=%d a[%d]=%d\n",pos,pos,a[pos]); } }